diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-07-25 23:16:38 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-07-25 23:16:38 +0000 |
commit | 47f3513dd574535aeb40c9eb11134f0899e92269 (patch) | |
tree | 7bd91987ca00ee4d618fbfd6038c24a60362993e /include | |
parent | 5a1cb644c903da49dc612a0ba5044505d066259e (diff) | |
download | external_llvm-47f3513dd574535aeb40c9eb11134f0899e92269.zip external_llvm-47f3513dd574535aeb40c9eb11134f0899e92269.tar.gz external_llvm-47f3513dd574535aeb40c9eb11134f0899e92269.tar.bz2 |
Initial implementation of 'fence' instruction, the new C++0x-style replacement for llvm.memory.barrier.
This is just a LangRef entry and reading/writing/memory representation; optimizer+codegen support coming soon.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136009 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 20 | ||||
-rw-r--r-- | include/llvm/Instruction.def | 63 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 93 | ||||
-rw-r--r-- | include/llvm/Support/IRBuilder.h | 4 | ||||
-rw-r--r-- | include/llvm/Support/InstVisitor.h | 1 |
5 files changed, 149 insertions, 32 deletions
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index df68bd5..503a867 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -218,6 +218,23 @@ namespace bitc { PEO_EXACT = 0 }; + /// Encoded AtomicOrdering values. + enum AtomicOrderingCodes { + ORDERING_NOTATOMIC = 0, + ORDERING_UNORDERED = 1, + ORDERING_MONOTONIC = 2, + ORDERING_ACQUIRE = 3, + ORDERING_RELEASE = 4, + ORDERING_ACQREL = 5, + ORDERING_SEQCST = 6 + }; + + /// Encoded SynchronizationScope values. + enum AtomicSynchScopeCodes { + SYNCHSCOPE_SINGLETHREAD = 0, + SYNCHSCOPE_CROSSTHREAD = 1 + }; + // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It // can contain a constant block (CONSTANTS_BLOCK_ID). enum FunctionCodes { @@ -266,7 +283,8 @@ namespace bitc { FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...] - FUNC_CODE_DEBUG_LOC = 35 // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_INST_FENCE = 36 // FENCE: [ordering, synchscope] }; } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 205f303..e418165 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -133,43 +133,44 @@ HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs HANDLE_MEMORY_INST(28, Store , StoreInst ) HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(29) +HANDLE_MEMORY_INST(30, Fence , FenceInst ) + LAST_MEMORY_INST(32) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(30) -HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(41) + FIRST_CAST_INST(33) +HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(44) // Other operators... - FIRST_OTHER_INST(42) -HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate - - LAST_OTHER_INST(54) + FIRST_OTHER_INST(45) +HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate + + LAST_OTHER_INST(57) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 72d60a3..89eb901 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -22,6 +22,7 @@ #include "llvm/CallingConv.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ErrorHandling.h" #include <iterator> namespace llvm { @@ -31,6 +32,22 @@ class ConstantRange; class APInt; class LLVMContext; +enum AtomicOrdering { + NotAtomic = 0, + Unordered = 1, + Monotonic = 2, + // Consume = 3, // Not specified yet. + Acquire = 4, + Release = 5, + AcquireRelease = 6, + SequentiallyConsistent = 7 +}; + +enum SynchronizationScope { + SingleThread = 0, + CrossThread = 1 +}; + //===----------------------------------------------------------------------===// // AllocaInst Class //===----------------------------------------------------------------------===// @@ -269,6 +286,82 @@ struct OperandTraits<StoreInst> : public FixedNumOperandTraits<StoreInst, 2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) //===----------------------------------------------------------------------===// +// FenceInst Class +//===----------------------------------------------------------------------===// + +/// FenceInst - an instruction for ordering other memory operations +/// +class FenceInst : public Instruction { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); +protected: + virtual FenceInst *clone_impl() const; +public: + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } + + // Ordering may only be Acquire, Release, AcquireRelease, or + // SequentiallyConsistent. + FenceInst(LLVMContext &C, AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread, + Instruction *InsertBefore = 0); + FenceInst(LLVMContext &C, AtomicOrdering Ordering, + SynchronizationScope SynchScope, + BasicBlock *InsertAtEnd); + + /// Returns the ordering effect of this fence. + AtomicOrdering getOrdering() const { + return AtomicOrdering(getSubclassDataFromInstruction() >> 1); + } + + /// Set the ordering constraint on this fence. May only be Acquire, Release, + /// AcquireRelease, or SequentiallyConsistent. + void setOrdering(AtomicOrdering Ordering) { + switch (Ordering) { + case Acquire: + case Release: + case AcquireRelease: + case SequentiallyConsistent: + setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + (Ordering << 1)); + return; + default: + llvm_unreachable("FenceInst ordering must be Acquire, Release," + " AcquireRelease, or SequentiallyConsistent"); + } + } + + SynchronizationScope getSynchScope() const { + return SynchronizationScope(getSubclassDataFromInstruction() & 1); + } + + /// Specify whether this fence orders other operations with respect to all + /// concurrently executing threads, or only with respect to signal handlers + /// executing in the same thread. + void setSynchScope(SynchronizationScope xthread) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + xthread); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FenceInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Fence; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +//===----------------------------------------------------------------------===// // GetElementPtrInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index caabbb9..0a2800e 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -762,6 +762,10 @@ public: StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } + FenceInst *CreateFence(AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + return Insert(new FenceInst(Context, Ordering, SynchScope)); + } Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &Name = "") { if (Constant *PC = dyn_cast<Constant>(Ptr)) { diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index b2e5d58..83b26f5 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -169,6 +169,7 @@ public: RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } + RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); } |