[llvm-commits] [llvm] r47430 - in /llvm/trunk: docs/LangRef.html include/llvm/CodeGen/SelectionDAG.h include/llvm/CodeGen/SelectionDAGNodes.h include/llvm/Intrinsics.td include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/Alpha/AlphaISelLowering.cpp lib/Target/Alpha/AlphaISelLowering.h lib/Target/Alpha/AlphaInstrInfo.td lib/Target/TargetSelectionDAG.td lib/Target/X86/X86InstrInfo.td
Evan Cheng
evan.cheng at apple.com
Wed Feb 20 23:35:50 PST 2008
On Feb 20, 2008, at 10:45 PM, Andrew Lenharth wrote:
Hi,
Some comments below.
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Thu Feb 21
> 00:45:13 2008
> @@ -356,6 +356,16 @@
> SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand
> Ptr,
> SDOperand SV);
>
> + /// getAtomic - Gets a node for an atomic op, produces result and
> chain, takes
> + // 3 operands
// -> ///
>
> + SDOperand getAtomic(unsigned Opcode, SDOperand Chain, SDOperand
> Ptr,
> + SDOperand A2, SDOperand A3, MVT::ValueType VT);
I know you described the operands in the doc. But please choose better
names than A2 and A3.
>
> +
> + /// getAtomic - Gets a node for an atomic op, produces result and
> chain, takes
> + // 2 operands
> + SDOperand getAtomic(unsigned Opcode, SDOperand Chain, SDOperand
> Ptr,
> + SDOperand A2, MVT::ValueType VT);
> +
> /// getLoad - Loads are not normal binary operators: their result
> type is not
> /// determined by their operands, and they produce a value AND a
> token chain.
> ///
>
> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Feb 21
> 00:45:13 2008
> @@ -441,7 +441,7 @@
> // is added / subtracted from the base pointer to form the
> address (for
> // indexed memory ops).
> LOAD, STORE,
> -
> +
> // DYNAMIC_STACKALLOC - Allocate some number of bytes on the
> stack aligned
> // to a specified boundary. This node always has two return
> values: a new
> // stack pointer value and a chain. The first operand is the
> token chain,
> @@ -591,12 +591,30 @@
>
> // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-
> load,
> // store-store, device)
> - // This corresponds to the atomic.barrier intrinsic.
> + // This corresponds to the memory.barrier intrinsic.
> // it takes an input chain, 4 operands to specify the type of
> barrier, an
> // operand specifying if the barrier applies to device and
> uncached memory
> // and produces an output chain.
> MEMBARRIER,
>
> + // Val, OUTCHAIN = ATOMIC_LCS(INCHAIN, ptr, cmp, swap)
> + // this corresponds to the atomic.lcs intrinsic.
> + // cmp is compared to *ptr, and if equal, swap is stored in *ptr.
> + // the return is always the original value in *ptr
> + ATOMIC_LCS,
> +
> + // Val, OUTCHAIN = ATOMIC_LAS(INCHAIN, ptr, amt)
> + // this corresponds to the atomic.las intrinsic.
> + // *ptr + amt is stored to *ptr atomically.
> + // the return is always the original value in *ptr
> + ATOMIC_LAS,
> +
> + // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
> + // this corresponds to the atomic.swap intrinsic.
> + // amt is stored to *ptr atomically.
> + // the return is always the original value in *ptr
> + ATOMIC_SWAP,
> +
> // BUILTIN_OP_END - This must be the last enum value in this list.
> BUILTIN_OP_END
> };
> @@ -1170,6 +1188,33 @@
> SDOperand getValue() const { return Op; }
> };
>
> +class AtomicSDNode : public SDNode {
> + virtual void ANCHOR(); // Out-of-line virtual method to give
> class a home.
> + SDOperand Ops[4];
> + MVT::ValueType OrigVT;
> +public:
> + AtomicSDNode(unsigned Opc, SDVTList VTL, SDOperand Chain,
> SDOperand X,
> + SDOperand Y, SDOperand Z, MVT::ValueType VT)
> + : SDNode(Opc, VTL) {
> + Ops[0] = Chain;
> + Ops[1] = X;
> + Ops[2] = Y;
> + Ops[3] = Z;
Do you need an assertion X.getValueType() == Y.getValueType()?
>
> + InitOperands(Ops, 4);
> + OrigVT=VT;
> + }
> + AtomicSDNode(unsigned Opc, SDVTList VTL, SDOperand Chain,
> SDOperand X,
> + SDOperand Y, MVT::ValueType VT)
> + : SDNode(Opc, VTL) {
> + Ops[0] = Chain;
> + Ops[1] = X;
> + Ops[2] = Y;
> + InitOperands(Ops, 3);
> + OrigVT=VT;
> + }
> + MVT::ValueType getVT() const { return OrigVT; }
> +};
How about accessors, e.g. getCompare() since you have gone through the
trouble of creating a new SDOperand subclass for it.
>
> +
> class StringSDNode : public SDNode {
> std::string Value;
> virtual void ANCHOR(); // Out-of-line virtual method to give
> class a home.
>
> Modified: llvm/trunk/include/llvm/Intrinsics.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/Intrinsics.td (original)
> +++ llvm/trunk/include/llvm/Intrinsics.td Thu Feb 21 00:45:13 2008
> @@ -64,7 +64,7 @@
> class LLVMMatchType<int num>
> : LLVMType<OtherVT>{
> int Number = num;
> -}
> +}
>
> def llvm_void_ty : LLVMType<isVoid>;
> def llvm_anyint_ty : LLVMType<iAny>;
> @@ -267,6 +267,17 @@
> def int_memory_barrier : Intrinsic<[llvm_void_ty, llvm_i1_ty,
> llvm_i1_ty,
> llvm_i1_ty, llvm_i1_ty,
> llvm_i1_ty], []>;
>
> +def int_atomic_lcs : Intrinsic<[llvm_anyint_ty,
> LLVMPointerType<LLVMMatchType<0>>,
> + LLVMMatchType<0>, LLVMMatchType<0>],
> + [IntrWriteArgMem]>,
> GCCBuiltin<"__sync_val_compare_and_swap">;
> +def int_atomic_las : Intrinsic<[llvm_anyint_ty,
> LLVMPointerType<LLVMMatchType<0>>,
> + LLVMMatchType<0>],
> + [IntrWriteArgMem]>,
> GCCBuiltin<"__sync_fetch_and_add">;
> +def int_atomic_swap : Intrinsic<[llvm_anyint_ty,
> LLVMPointerType<LLVMMatchType<0>>,
> + LLVMMatchType<0>],
> + [IntrWriteArgMem]>,
> GCCBuiltin<"__sync_lock_test_and_set">;
> +
> +
> //===-------------------------- Other Intrinsics
> --------------------------===//
> //
> def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
>
> Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Feb 21
> 00:45:13 2008
> @@ -1252,7 +1252,7 @@
> /// TargetDAGCombineArray - Targets can specify ISD nodes that
> they would
> /// like PerformDAGCombine callbacks for by calling
> setTargetDAGCombine(),
> /// which sets a bit in this array.
> - unsigned char TargetDAGCombineArray[156/(sizeof(unsigned char)*8)];
> + unsigned char TargetDAGCombineArray[160/(sizeof(unsigned char)*8)];
I don't think this ought be changed. It should be the same size as
OpActions. Although I don't know where 156 comes from. Anyone?
>
>
> /// PromoteToType - For operations that must be promoted to a
> specific type,
> /// this holds the destination type. This map should be sparse,
> so don't hold
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Thu Feb 21
> 00:45:13 2008
> @@ -1153,6 +1153,31 @@
> break;
> }
>
> + case ISD::ATOMIC_LCS:
> + case ISD::ATOMIC_LAS:
> + 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 MemBarrier node!");
> + int num = Node->getOpcode() == ISD::ATOMIC_LCS ? 4 : 3;
> + MVT::ValueType VT = Node->getValueType(0);
> + switch (TLI.getOperationAction(ISD::ATOMIC_LCS, VT)) {
> + default: assert(0 && "This action is not supported yet!");
> + case TargetLowering::Legal: {
> + SDOperand Ops[4];
> + for (int x = 0; x < num; ++x)
> + Ops[x] = LegalizeOp(Node->getOperand(x));
> + Result = DAG.UpdateNodeOperands(Result, &Ops[0], num);
> + AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
> + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
> + return Result.getValue(Op.ResNo);
> + break;
> + }
> + }
> + break;
> + }
> +
> case ISD::Constant: {
> ConstantSDNode *CN = cast<ConstantSDNode>(Node);
> unsigned opAction =
> @@ -4228,6 +4253,27 @@
> break;
> }
>
> + case ISD::ATOMIC_LCS: {
> + Tmp2 = PromoteOp(Node->getOperand(2));
> + Tmp3 = PromoteOp(Node->getOperand(3));
> + Result = DAG.getAtomic(Node->getOpcode(), Node->getOperand(0),
> + Node->getOperand(1), Tmp2, Tmp3,
> + cast<AtomicSDNode>(Node)->getVT());
> + // Remember that we legalized the chain.
> + AddLegalizedOperand(Op.getValue(1),
> LegalizeOp(Result.getValue(1)));
> + break;
> + }
> + case ISD::ATOMIC_LAS:
> + case ISD::ATOMIC_SWAP: {
> + Tmp2 = PromoteOp(Node->getOperand(2));
> + Result = DAG.getAtomic(Node->getOpcode(), Node->getOperand(0),
> + Node->getOperand(1), Tmp2,
> + cast<AtomicSDNode>(Node)->getVT());
> + // Remember that we legalized the chain.
> + AddLegalizedOperand(Op.getValue(1),
> LegalizeOp(Result.getValue(1)));
> + break;
> + }
> +
> case ISD::AND:
> case ISD::OR:
> case ISD::XOR:
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Feb 21
> 00:45:13 2008
> @@ -2427,6 +2427,43 @@
> return getNode(ISD::MEMSET, MVT::Other, Ops, 6);
> }
>
> +SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain,
> + SDOperand Ptr, SDOperand A2,
> + SDOperand A3, MVT::ValueType VT) {
> + assert(Opcode == ISD::ATOMIC_LCS && "Invalid Atomic Op");
> + SDVTList VTs = getVTList(A2.getValueType(), MVT::Other);
> + FoldingSetNodeID ID;
> + SDOperand Ops[] = {Chain, Ptr, A2, A3};
> + AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
> + ID.AddInteger((unsigned int)VT);
> + void* IP = 0;
> + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
> + return SDOperand(E, 0);
> + SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, A2, A3, VT);
> + CSEMap.InsertNode(N, IP);
> + AllNodes.push_back(N);
> + return SDOperand(N, 0);
> +}
> +
> +SDOperand SelectionDAG::getAtomic(unsigned Opcode, SDOperand Chain,
> + SDOperand Ptr, SDOperand A2,
> + MVT::ValueType VT) {
> + assert((Opcode == ISD::ATOMIC_LAS || Opcode == ISD::ATOMIC_SWAP)
> + && "Invalid Atomic Op");
> + SDVTList VTs = getVTList(A2.getValueType(), MVT::Other);
> + FoldingSetNodeID ID;
> + SDOperand Ops[] = {Chain, Ptr, A2};
> + AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
> + ID.AddInteger((unsigned int)VT);
> + void* IP = 0;
> + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
> + return SDOperand(E, 0);
> + SDNode* N = new AtomicSDNode(Opcode, VTs, Chain, Ptr, A2, VT);
> + CSEMap.InsertNode(N, IP);
> + AllNodes.push_back(N);
> + return SDOperand(N, 0);
> +}
> +
> SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
> SDOperand Chain, SDOperand Ptr,
> const Value *SV, int SVOffset,
> @@ -3593,6 +3630,7 @@
> void VTSDNode::ANCHOR() {}
> void LoadSDNode::ANCHOR() {}
> void StoreSDNode::ANCHOR() {}
> +void AtomicSDNode::ANCHOR() {}
>
> HandleSDNode::~HandleSDNode() {
> SDVTList VTs = { 0, 0 };
> @@ -3821,6 +3859,9 @@
> }
>
> 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::PCMARKER: return "PCMarker";
> case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
> case ISD::SRCVALUE: return "SrcValue";
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Feb
> 21 00:45:13 2008
> @@ -221,7 +221,7 @@
>
> /// isUsedOutsideOfDefiningBlock - Return true if this instruction
> is used by
> /// PHI nodes or outside of the basic block that defines it, or used
> by a
> -/// switch instruction, which may expand to multiple basic blocks.
> +/// switch or atomic instruction, which may expand to multiple
> basic blocks.
> static bool isUsedOutsideOfDefiningBlock(Instruction *I) {
> if (isa<PHINode>(I)) return true;
> BasicBlock *BB = I->getParent();
> @@ -3059,6 +3059,38 @@
> DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
> return 0;
> }
> + case Intrinsic::atomic_lcs: {
> + SDOperand Root = getRoot();
> + SDOperand O3 = getValue(I.getOperand(3));
> + SDOperand L = DAG.getAtomic(ISD::ATOMIC_LCS, Root,
> + getValue(I.getOperand(1)),
> + getValue(I.getOperand(2)),
> + O3, O3.getValueType());
> + setValue(&I, L);
> + 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;
> + }
> +
> }
> }
>
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Thu Feb 21
> 00:45:13 2008
> @@ -629,3 +629,96 @@
>
> return std::vector<unsigned>();
> }
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +// Other Lowering Code
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +
> +MachineBasicBlock *
> +AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
> + MachineBasicBlock
> *BB) {
> + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
> + assert((MI->getOpcode() == Alpha::CAS32 ||
> + MI->getOpcode() == Alpha::CAS64 ||
> + MI->getOpcode() == Alpha::LAS32 ||
> + MI->getOpcode() == Alpha::LAS64 ||
> + MI->getOpcode() == Alpha::SWAP32 ||
> + MI->getOpcode() == Alpha::SWAP64) &&
> + "Unexpected instr type to insert");
> +
> + bool is32 = MI->getOpcode() == Alpha::CAS32 ||
> + MI->getOpcode() == Alpha::LAS32 ||
> + MI->getOpcode() == Alpha::SWAP32;
> +
> + //Load locked store conditional for atomic ops take on the same
> form
> + //start:
> + //ll
> + //do stuff (maybe branch to exit)
> + //sc
> + //test sc and maybe branck to start
> + //exit:
> + const BasicBlock *LLVM_BB = BB->getBasicBlock();
> + ilist<MachineBasicBlock>::iterator It = BB;
> + ++It;
> +
> + MachineBasicBlock *thisMBB = BB;
> + MachineBasicBlock *llscMBB = new MachineBasicBlock(LLVM_BB);
> + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
> +
> + for(MachineBasicBlock::succ_iterator i = thisMBB->succ_begin(),
> + e = thisMBB->succ_end(); i != e; ++i)
> + sinkMBB->addSuccessor(*i);
> + while(!thisMBB->succ_empty())
> + thisMBB->removeSuccessor(thisMBB->succ_begin());
> +
> + MachineFunction *F = BB->getParent();
> + F->getBasicBlockList().insert(It, llscMBB);
> + F->getBasicBlockList().insert(It, sinkMBB);
> +
> + BuildMI(thisMBB, TII->get(Alpha::BR)).addMBB(llscMBB);
> +
> + unsigned reg_res = MI->getOperand(0).getReg(),
> + reg_ptr = MI->getOperand(1).getReg(),
> + reg_v2 = MI->getOperand(2).getReg(),
> + reg_store = F-
> >getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
> +
> + BuildMI(llscMBB, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L),
> + reg_res).addImm(0).addReg(reg_ptr);
> + switch (MI->getOpcode()) {
> + case Alpha::CAS32:
> + case Alpha::CAS64: {
> + unsigned reg_cmp
> + = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
> + BuildMI(llscMBB, TII->get(Alpha::CMPEQ), reg_cmp)
> + .addReg(reg_v2).addReg(reg_res);
> + BuildMI(llscMBB, TII->get(Alpha::BEQ))
> + .addImm(0).addReg(reg_cmp).addMBB(sinkMBB);
> + BuildMI(llscMBB, TII->get(Alpha::BISr), reg_store)
> + .addReg(Alpha::R31).addReg(MI->getOperand(3).getReg());
> + break;
> + }
> + case Alpha::LAS32:
> + case Alpha::LAS64: {
> + BuildMI(llscMBB, TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr),
> reg_store)
> + .addReg(reg_res).addReg(reg_v2);
> + break;
> + }
> + case Alpha::SWAP32:
> + case Alpha::SWAP64: {
> + BuildMI(llscMBB, TII->get(Alpha::BISr), reg_store)
> + .addReg(reg_v2).addReg(reg_v2);
> + break;
> + }
> + }
> + BuildMI(llscMBB, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C),
> reg_store)
> + .addReg(reg_store).addImm(0).addReg(reg_ptr);
> + BuildMI(llscMBB, TII->get(Alpha::BEQ))
> + .addImm(0).addReg(reg_store).addMBB(llscMBB);
> + BuildMI(llscMBB, TII->get(Alpha::BR)).addMBB(sinkMBB);
> +
> + thisMBB->addSuccessor(llscMBB);
> + llscMBB->addSuccessor(llscMBB);
> + llscMBB->addSuccessor(sinkMBB);
> + delete MI; // The pseudo instruction is gone now.
> +
> + return sinkMBB;
> +}
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.h Thu Feb 21
> 00:45:13 2008
> @@ -88,6 +88,9 @@
> MVT::ValueType VT) const;
>
> bool hasITOF() { return useITOF; }
> +
> + MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
> +
> MachineBasicBlock *BB);
> };
> }
>
>
> Modified: llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/Alpha/AlphaInstrInfo.td Thu Feb 21
> 00:45:13 2008
> @@ -167,6 +167,23 @@
> "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
>
>
> +let usesCustomDAGSchedInserter = 1 in { // Expanded by the
> scheduler.
> +def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $cmp, GPRC:$swp), "",
> + [(set GPRC:$dst, (atomic_lcs_32 GPRC:$ptr, GPRC:$cmp, GPRC:
> $swp))], s_pseudo>;
> +def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $cmp, GPRC:$swp), "",
> + [(set GPRC:$dst, (atomic_lcs_64 GPRC:$ptr, GPRC:$cmp, GPRC:
> $swp))], s_pseudo>;
> +
> +def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $swp), "",
> + [(set GPRC:$dst, (atomic_las_32 GPRC:$ptr, GPRC:$swp))],
> s_pseudo>;
> +def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $swp), "",
> + [(set GPRC:$dst, (atomic_las_64 GPRC:$ptr, GPRC:$swp))],
> s_pseudo>;
> +
> +def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $swp), "",
> + [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))],
> s_pseudo>;
> +def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:
> $swp), "",
> + [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))],
> s_pseudo>;
> +}
> +
> //***********************
> //Real instructions
> //***********************
> @@ -568,6 +585,18 @@
> def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
> (LDQl texternalsym:$ext, GPRC:$RB)>;
>
> +let OutOperandList = (outs GPRC:$RR),
> + InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB),
> + Constraints = "$RA = $RR",
> + DisableEncoding = "$RR" in {
> +def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>;
> +def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>;
> +}
> +let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:
> $DISP, GPRC:$RB) in {
> +def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>;
> +def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>;
> +}
> +
> def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process
> cycle counter
> def MB : MfcPForm<0x18, 0x4000, "mb", s_imisc>; //memory barrier
> def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory
> barrier
> @@ -965,7 +994,6 @@
> //S_floating : IEEE Single
> //T_floating : IEEE Double
>
> -
> //Unused instructions
> //Mnemonic Format Opcode Description
> //CALL_PAL Pcd 00 Trap to PALcode
> @@ -973,12 +1001,8 @@
> //EXCB Mfc 18.0400 Exception barrier
> //FETCH Mfc 18.8000 Prefetch data
> //FETCH_M Mfc 18.A000 Prefetch data, modify intent
> -//LDL_L Mem 2A Load sign-extended longword locked
> -//LDQ_L Mem 2B Load quadword locked
> //LDQ_U Mem 0B Load unaligned quadword
> //MB Mfc 18.4000 Memory barrier
> -//STL_C Mem 2E Store longword conditional
> -//STQ_C Mem 2F Store quadword conditional
> //STQ_U Mem 0F Store unaligned quadword
> //TRAPB Mfc 18.0000 Trap barrier
> //WH64 Mfc 18.F800 Write hint 64 bytes
>
> Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original)
> +++ llvm/trunk/lib/Target/TargetSelectionDAG.td Thu Feb 21 00:45:13
> 2008
> @@ -189,6 +189,12 @@
> SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>,
> SDTCisSameAs<0,4>,
> SDTCisInt<0>
> ]>;
> +def STDAtomic3 : SDTypeProfile<1, 3, [
> + SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1>
> +]>;
> +def STDAtomic2 : SDTypeProfile<1, 2, [
> + SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
> +]>;
>
> class SDCallSeqStart<list<SDTypeConstraint> constraints> :
> SDTypeProfile<0, 1, constraints>;
> @@ -336,6 +342,13 @@
> [SDNPHasChain, SDNPSideEffect]>;
> def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier,
> [SDNPHasChain, SDNPSideEffect]>;
> +// Do not use atomic_* directly, use atomic_*_size (see below)
> +def atomic_lcs : SDNode<"ISD::ATOMIC_LCS", STDAtomic3,
> + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
> +def atomic_las : SDNode<"ISD::ATOMIC_LAS", STDAtomic2,
> + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
> +def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", STDAtomic2,
> + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
>
> // Do not use ld, st directly. Use load, extload, sextload,
> zextload, store,
> // and truncst (see below).
> @@ -722,6 +735,84 @@
> return false;
> }]>;
>
> +//Atomic patterns
> +def atomic_lcs_8 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp),
> + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i8;
> + return false;
> +}]>;
> +def atomic_lcs_16 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp),
> + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i16;
> + return false;
> +}]>;
> +def atomic_lcs_32 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp),
> + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i32;
> + return false;
> +}]>;
> +def atomic_lcs_64 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp),
> + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i64;
> + return false;
> +}]>;
> +
> +def atomic_las_8 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_las node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i8;
> + return false;
> +}]>;
> +def atomic_las_16 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_las node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i16;
> + return false;
> +}]>;
> +def atomic_las_32 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_las node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i32;
> + return false;
> +}]>;
> +def atomic_las_64 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_las node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i64;
> + return false;
> +}]>;
> +
> +def atomic_swap_8 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_swap node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i8;
> + return false;
> +}]>;
> +def atomic_swap_16 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_swap node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i16;
> + return false;
> +}]>;
> +def atomic_swap_32 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_swap node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i32;
> + return false;
> +}]>;
> +def atomic_swap_64 : PatFrag<(ops node:$ptr, node:$inc),
> + (atomic_swap node:$ptr, node:$inc), [{
> + if (AtomicSDNode* V = dyn_cast<AtomicSDNode>(N))
> + return V->getVT() == MVT::i64;
> + return false;
> +}]>;
> +
> +
> +
> // setcc convenience fragments.
> def setoeq : PatFrag<(ops node:$lhs, node:$rhs),
> (setcc node:$lhs, node:$rhs, SETOEQ)>;
>
> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=47430&r1=47429&r2=47430&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Feb 21 00:45:13 2008
> @@ -2536,6 +2536,15 @@
> }
>
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +// Atomic support
> +//
> +let Defs = [EAX] in
> +def LCMPXCHGL : I<0, Pseudo, (outs GR32:$dst),
> + (ins GR32:$ptr, GR32:$cmp, GR32:$swap),
> + "movl $cmp, %eax ; lock cmpxchgl $swap,($ptr) ;
> movl %eax, $dst",
> + [(set GR32:$dst, (atomic_lcs_32 GR32:$ptr,
> GR32:$cmp, GR32:$swap))]>;
How about JIT support? This has to be handled specially in
X86CodeEmitter.
Thanks,
Evan
>
> +
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> // Non-Instruction Patterns
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
>
> @@ -2683,7 +2692,6 @@
> (srl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
> (SHLD16mrCL addr:$dst, GR16:$src2)>;
>
> -
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> // Floating Point Stack Support
> //
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list