diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 56 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 63 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 |
5 files changed, 113 insertions, 37 deletions
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 58ca6efcfe..01aaba5282 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -252,6 +252,19 @@ void MachineBasicBlock::removePredecessor(MachineBasicBlock *pred) { Predecessors.erase(I); } +void MachineBasicBlock::transferSuccessors(MachineBasicBlock *fromMBB) +{ + if (this == fromMBB) + return; + + for(MachineBasicBlock::succ_iterator iter = fromMBB->succ_begin(), + end = fromMBB->succ_end(); iter != end; ++iter) { + addSuccessor(*iter); + } + while(!fromMBB->succ_empty()) + fromMBB->removeSuccessor(fromMBB->succ_begin()); +} + bool MachineBasicBlock::isSuccessor(MachineBasicBlock *MBB) const { std::vector<MachineBasicBlock *>::const_iterator I = std::find(Successors.begin(), Successors.end(), MBB); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f8e44ec695..4aa38cd1fa 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1235,32 +1235,58 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { break; } - case ISD::ATOMIC_LCS: + case ISD::ATOMIC_LCS: { + unsigned int num_operands = 4; + assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!"); + SDOperand Ops[4]; + for (unsigned int x = 0; x < num_operands; ++x) + Ops[x] = LegalizeOp(Node->getOperand(x)); + Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands); + + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Result, DAG); + break; + case TargetLowering::Legal: + break; + } + AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + } case ISD::ATOMIC_LAS: + case ISD::ATOMIC_LSS: + case ISD::ATOMIC_LOAD_AND: + case ISD::ATOMIC_LOAD_OR: + case ISD::ATOMIC_LOAD_XOR: + case ISD::ATOMIC_LOAD_MIN: + case ISD::ATOMIC_LOAD_MAX: + case ISD::ATOMIC_LOAD_UMIN: + case ISD::ATOMIC_LOAD_UMAX: case ISD::ATOMIC_SWAP: { - assert(((Node->getNumOperands() == 4 && Node->getOpcode() == ISD::ATOMIC_LCS) || - (Node->getNumOperands() == 3 && Node->getOpcode() == ISD::ATOMIC_LAS) || - (Node->getNumOperands() == 3 && Node->getOpcode() == ISD::ATOMIC_SWAP)) && - "Invalid Atomic node!"); - int num = Node->getOpcode() == ISD::ATOMIC_LCS ? 4 : 3; - SDOperand Ops[4]; - for (int x = 0; x < num; ++x) + unsigned int num_operands = 3; + assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!"); + SDOperand Ops[3]; + for (unsigned int x = 0; x < num_operands; ++x) Ops[x] = LegalizeOp(Node->getOperand(x)); - Result = DAG.UpdateNodeOperands(Result, &Ops[0], num); + Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands); switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Custom: Result = TLI.LowerOperation(Result, DAG); break; + case TargetLowering::Expand: + Result = SDOperand(TLI.ExpandOperationResult(Op.Val, DAG),0); + break; case TargetLowering::Legal: break; } AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0)); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); - } - + } case ISD::Constant: { ConstantSDNode *CN = cast<ConstantSDNode>(Node); unsigned opAction = @@ -4242,6 +4268,14 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { break; } case ISD::ATOMIC_LAS: + case ISD::ATOMIC_LSS: + case ISD::ATOMIC_LOAD_AND: + case ISD::ATOMIC_LOAD_OR: + case ISD::ATOMIC_LOAD_XOR: + case ISD::ATOMIC_LOAD_MIN: + case ISD::ATOMIC_LOAD_MAX: + case ISD::ATOMIC_LOAD_UMIN: + case ISD::ATOMIC_LOAD_UMAX: case ISD::ATOMIC_SWAP: { Tmp2 = PromoteOp(Node->getOperand(2)); Result = DAG.getAtomic(Node->getOpcode(), Node->getOperand(0), diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6b2f54393d..26d5548617 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2855,7 +2855,11 @@ SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain, SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain, SDOperand Ptr, SDOperand Val, MVT::ValueType VT) { - assert((Opcode == ISD::ATOMIC_LAS || Opcode == ISD::ATOMIC_SWAP) + assert(( Opcode == ISD::ATOMIC_LAS || Opcode == ISD::ATOMIC_LSS + || Opcode == ISD::ATOMIC_SWAP || Opcode == ISD::ATOMIC_LOAD_AND + || Opcode == ISD::ATOMIC_LOAD_OR || Opcode == ISD::ATOMIC_LOAD_XOR + || Opcode == ISD::ATOMIC_LOAD_MIN || Opcode == ISD::ATOMIC_LOAD_MAX + || Opcode == ISD::ATOMIC_LOAD_UMIN || Opcode == ISD::ATOMIC_LOAD_UMAX) && "Invalid Atomic Op"); SDVTList VTs = getVTList(Val.getValueType(), MVT::Other); FoldingSetNodeID ID; @@ -4269,7 +4273,15 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::MEMBARRIER: return "MemBarrier"; case ISD::ATOMIC_LCS: return "AtomicLCS"; case ISD::ATOMIC_LAS: return "AtomicLAS"; - case ISD::ATOMIC_SWAP: return "AtomicSWAP"; + case ISD::ATOMIC_LSS: return "AtomicLSS"; + case ISD::ATOMIC_LOAD_AND: return "AtomicLoadAnd"; + case ISD::ATOMIC_LOAD_OR: return "AtomicLoadOr"; + case ISD::ATOMIC_LOAD_XOR: return "AtomicLoadXor"; + case ISD::ATOMIC_LOAD_MIN: return "AtomicLoadMin"; + case ISD::ATOMIC_LOAD_MAX: return "AtomicLoadMax"; + case ISD::ATOMIC_LOAD_UMIN: return "AtomicLoadUMin"; + case ISD::ATOMIC_LOAD_UMAX: return "AtomicLoadUMax"; + case ISD::ATOMIC_SWAP: return "AtomicSWAP"; case ISD::PCMARKER: return "PCMarker"; case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; case ISD::SRCVALUE: return "SrcValue"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 7fc5d61705..15e3629849 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -732,6 +732,10 @@ public: assert(0 && "UserOp2 should not exist at instruction selection time!"); abort(); } + +private: + inline const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op); + }; } // end namespace llvm @@ -2769,6 +2773,22 @@ static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI, } } + +/// Inlined utility function to implement binary input atomic intrinsics for +// visitIntrinsicCall: I is a call instruction +// Op is the associated NodeType for I +const char * +SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) { + SDOperand Root = getRoot(); + SDOperand O2 = getValue(I.getOperand(2)); + SDOperand L = DAG.getAtomic(Op, Root, + getValue(I.getOperand(1)), + O2, O2.getValueType()); + setValue(&I, L); + DAG.setRoot(L.getValue(1)); + return 0; +} + /// visitIntrinsicCall - Lower the call to the specified intrinsic function. If /// we want to emit this as a call to a named external function, return the name /// otherwise lower it and return null. @@ -3205,27 +3225,26 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.setRoot(L.getValue(1)); return 0; } - case Intrinsic::atomic_las: { - SDOperand Root = getRoot(); - SDOperand O2 = getValue(I.getOperand(2)); - SDOperand L = DAG.getAtomic(ISD::ATOMIC_LAS, Root, - getValue(I.getOperand(1)), - O2, O2.getValueType()); - setValue(&I, L); - DAG.setRoot(L.getValue(1)); - return 0; - } - case Intrinsic::atomic_swap: { - SDOperand Root = getRoot(); - SDOperand O2 = getValue(I.getOperand(2)); - SDOperand L = DAG.getAtomic(ISD::ATOMIC_SWAP, Root, - getValue(I.getOperand(1)), - O2, O2.getValueType()); - setValue(&I, L); - DAG.setRoot(L.getValue(1)); - return 0; - } - + case Intrinsic::atomic_las: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LAS); + case Intrinsic::atomic_lss: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LSS); + case Intrinsic::atomic_load_and: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND); + case Intrinsic::atomic_load_or: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR); + case Intrinsic::atomic_load_xor: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR); + case Intrinsic::atomic_load_min: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN); + case Intrinsic::atomic_load_max: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX); + case Intrinsic::atomic_load_umin: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN); + case Intrinsic::atomic_load_umax: + return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX); + case Intrinsic::atomic_swap: + return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP); } } @@ -4519,8 +4538,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } - - bool SelectionDAGISel::runOnFunction(Function &Fn) { // Get alias analysis for load/store combining. AA = &getAnalysis<AliasAnalysis>(); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 5ccad9ebf8..371fbab2b8 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -165,7 +165,7 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) { TargetLowering::TargetLowering(TargetMachine &tm) : TM(tm), TD(TM.getTargetData()) { - assert(ISD::BUILTIN_OP_END <= 156 && + assert(ISD::BUILTIN_OP_END <= OpActionsCapacity && "Fixed size array in TargetLowering is not large enough!"); // All operations default to being supported. memset(OpActions, 0, sizeof(OpActions)); |