diff options
Diffstat (limited to 'include')
48 files changed, 1217 insertions, 303 deletions
diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h index a31dc82..9877b8d 100644 --- a/include/llvm-c/ExecutionEngine.h +++ b/include/llvm-c/ExecutionEngine.h @@ -26,6 +26,9 @@ extern "C" { #endif +void LLVMLinkInJIT(void); +void LLVMLinkInInterpreter(void); + typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef; typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef; diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index 5de5bc7..bb423bb 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -20,6 +20,7 @@ #define LLVM_C_TARGET_H #include "llvm-c/Core.h" +#include "llvm/Config/config.h" #ifdef __cplusplus extern "C" { @@ -31,6 +32,34 @@ typedef int LLVMByteOrdering; typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; typedef struct LLVMStructLayout *LLVMStructLayoutRef; +/* Declare all of the target-initialization functions that are available. */ +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); +#include "llvm/Config/Targets.def" + +/** LLVMInitializeAllTargets - The main program should call this function if it + wants to link in all available targets that LLVM is configured to + support. */ +static inline void LLVMInitializeAllTargets() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); +#include "llvm/Config/Targets.def" +} + +/** LLVMInitializeNativeTarget - The main program should call this function to + initialize the native target corresponding to the host. This is useful + for JIT applications to ensure that the target gets linked in correctly. */ +static inline int LLVMInitializeNativeTarget() { + /* If we have a native target, initialize it to ensure it is linked in. */ +#ifdef LLVM_NATIVE_ARCH +#define DoInit2(TARG) LLVMInitialize ## TARG () +#define DoInit(T) DoInit2(T) + DoInit(LLVM_NATIVE_ARCH); + return 0; +#undef DoInit +#undef DoInit2 +#else + return 1; +#endif +} /*===-- Target Data -------------------------------------------------------===*/ diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 537f866..484ff5f 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -26,14 +26,16 @@ #ifndef LLVM_ADT_STATISTIC_H #define LLVM_ADT_STATISTIC_H +#include "llvm/System/Atomic.h" + namespace llvm { class Statistic { public: const char *Name; const char *Desc; - unsigned Value : 31; - bool Initialized : 1; + unsigned Value; + bool Initialized; unsigned getValue() const { return Value; } const char *getName() const { return Name; } @@ -47,19 +49,60 @@ public: // Allow use of this class as the value itself. operator unsigned() const { return Value; } - const Statistic &operator=(unsigned Val) { Value = Val; return init(); } - const Statistic &operator++() { ++Value; return init(); } - unsigned operator++(int) { init(); return Value++; } - const Statistic &operator--() { --Value; return init(); } - unsigned operator--(int) { init(); return Value--; } - const Statistic &operator+=(const unsigned &V) { Value += V; return init(); } - const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); } - const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); } - const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); } + const Statistic &operator=(unsigned Val) { + Value = Val; + return init(); + } + + const Statistic &operator++() { + sys::AtomicIncrement(&Value); + return init(); + } + + unsigned operator++(int) { + init(); + unsigned OldValue = Value; + sys::AtomicIncrement(&Value); + return OldValue; + } + + const Statistic &operator--() { + sys::AtomicDecrement(&Value); + return init(); + } + + unsigned operator--(int) { + init(); + unsigned OldValue = Value; + sys::AtomicDecrement(&Value); + return OldValue; + } + + const Statistic &operator+=(const unsigned &V) { + sys::AtomicAdd(&Value, V); + return init(); + } + + const Statistic &operator-=(const unsigned &V) { + sys::AtomicAdd(&Value, -V); + return init(); + } + + const Statistic &operator*=(const unsigned &V) { + sys::AtomicMul(&Value, V); + return init(); + } + + const Statistic &operator/=(const unsigned &V) { + sys::AtomicDiv(&Value, V); + return init(); + } protected: Statistic &init() { - if (!Initialized) RegisterStatistic(); + bool tmp = Initialized; + sys::MemoryFence(); + if (!tmp) RegisterStatistic(); return *this; } void RegisterStatistic(); diff --git a/include/llvm/ADT/Trie.h b/include/llvm/ADT/Trie.h index 70f3b41..ed94f9d 100644 --- a/include/llvm/ADT/Trie.h +++ b/include/llvm/ADT/Trie.h @@ -308,7 +308,8 @@ struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits { return "Trie"; } - static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) { + static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T, + bool ShortNames) { if (T.getRoot() == Node) return "<Root>"; else diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index 972bb07..20de3a4 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -20,6 +20,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Dwarf.h" namespace llvm { @@ -36,7 +37,7 @@ namespace llvm { class DIDescriptor { protected: - GlobalVariable *GV; + GlobalVariable *DbgGV; /// DIDescriptor constructor. If the specified GV is non-null, this checks /// to make sure that the tag in the descriptor matches 'RequiredTag'. If @@ -58,12 +59,12 @@ namespace llvm { GlobalVariable *getGlobalVariableField(unsigned Elt) const; public: - explicit DIDescriptor() : GV(0) {} - explicit DIDescriptor(GlobalVariable *gv) : GV(gv) {} + explicit DIDescriptor() : DbgGV(0) {} + explicit DIDescriptor(GlobalVariable *GV) : DbgGV(GV) {} - bool isNull() const { return GV == 0; } + bool isNull() const { return DbgGV == 0; } - GlobalVariable *getGV() const { return GV; } + GlobalVariable *getGV() const { return DbgGV; } unsigned getVersion() const { return getUnsignedField(0) & LLVMDebugVersionMask; @@ -80,15 +81,6 @@ namespace llvm { void dump() const; }; - /// DIAnchor - A wrapper for various anchor descriptors. - class DIAnchor : public DIDescriptor { - public: - explicit DIAnchor(GlobalVariable *GV = 0) - : DIDescriptor(GV, dwarf::DW_TAG_anchor) {} - - unsigned getAnchorTag() const { return getUnsignedField(1); } - }; - /// DISubrange - This is used to represent ranges, for array bounds. class DISubrange : public DIDescriptor { public: @@ -245,7 +237,7 @@ namespace llvm { explicit DIDerivedType(GlobalVariable *GV) : DIType(GV, true, true) { if (GV && !isDerivedType(getTag())) - GV = 0; + DbgGV = 0; } DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); } @@ -265,7 +257,7 @@ namespace llvm { explicit DICompositeType(GlobalVariable *GV) : DIDerivedType(GV, true, true) { if (GV && !isCompositeType(getTag())) - GV = 0; + DbgGV = 0; } DIArray getTypeArray() const { return getFieldAs<DIArray>(10); } @@ -330,6 +322,19 @@ namespace llvm { DICompositeType getType() const { return getFieldAs<DICompositeType>(8); } + /// getReturnTypeName - Subprogram return types are encoded either as + /// DIType or as DICompositeType. + const std::string &getReturnTypeName(std::string &F) const { + DICompositeType DCT(getFieldAs<DICompositeType>(8)); + if (!DCT.isNull()) { + DIArray A = DCT.getTypeArray(); + DIType T(A.getElement(0).getGV()); + return T.getName(F); + } + DIType T(getFieldAs<DIType>(8)); + return T.getName(F); + } + /// Verify - Verify that a subprogram descriptor is well formed. bool Verify() const; @@ -360,10 +365,10 @@ namespace llvm { /// global etc). class DIVariable : public DIDescriptor { public: - explicit DIVariable(GlobalVariable *gv = 0) - : DIDescriptor(gv) { - if (gv && !isVariable(getTag())) - GV = 0; + explicit DIVariable(GlobalVariable *GV = 0) + : DIDescriptor(GV) { + if (GV && !isVariable(getTag())) + DbgGV = 0; } DIDescriptor getContext() const { return getDescriptorField(1); } @@ -398,7 +403,6 @@ namespace llvm { class DIFactory { Module &M; // Cached values for uniquing and faster lookups. - DIAnchor CompileUnitAnchor, SubProgramAnchor, GlobalVariableAnchor; const Type *EmptyStructPtr; // "{}*". Function *StopPointFn; // llvm.dbg.stoppoint Function *FuncStartFn; // llvm.dbg.func.start @@ -413,18 +417,6 @@ namespace llvm { public: explicit DIFactory(Module &m); - /// GetOrCreateCompileUnitAnchor - Return the anchor for compile units, - /// creating a new one if there isn't already one in the module. - DIAnchor GetOrCreateCompileUnitAnchor(); - - /// GetOrCreateSubprogramAnchor - Return the anchor for subprograms, - /// creating a new one if there isn't already one in the module. - DIAnchor GetOrCreateSubprogramAnchor(); - - /// GetOrCreateGlobalVariableAnchor - Return the anchor for globals, - /// creating a new one if there isn't already one in the module. - DIAnchor GetOrCreateGlobalVariableAnchor(); - /// GetOrCreateArray - Create an descriptor for an array of descriptors. /// This implicitly uniques the arrays created. DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys); @@ -527,7 +519,6 @@ namespace llvm { private: Constant *GetTagConstant(unsigned TAG); Constant *GetStringConstant(const std::string &String); - DIAnchor GetOrCreateAnchor(unsigned TAG, const char *Name); /// getCastToEmpty - Return the descriptor as a Constant* with type '{}*'. Constant *getCastToEmpty(DIDescriptor D); @@ -550,6 +541,13 @@ namespace llvm { bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type, unsigned &LineNo, std::string &File, std::string &Dir); + + /// CollectDebugInfoAnchors - Collect debugging information anchors. + void CollectDebugInfoAnchors(Module &M, + SmallVector<GlobalVariable *, 2> &CompileUnits, + SmallVector<GlobalVariable *, 4> &GlobalVars, + SmallVector<GlobalVariable *, 4> &Subprograms); + } // end namespace llvm #endif diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h new file mode 100644 index 0000000..c69bc60 --- /dev/null +++ b/include/llvm/Analysis/LoopDependenceAnalysis.h @@ -0,0 +1,52 @@ +//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory +// accesses in loops. +// +// Please note that this is work in progress and the interface is subject to +// change. +// +// TODO: adapt as interface progresses +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H +#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H + +#include "llvm/Analysis/LoopPass.h" + +namespace llvm { + + class AnalysisUsage; + class LoopPass; + class ScalarEvolution; + + class LoopDependenceAnalysis : public LoopPass { + Loop *L; + ScalarEvolution *SE; + + public: + static char ID; // Class identification, replacement for typeinfo + LoopDependenceAnalysis() : LoopPass(&ID) {} + + bool runOnLoop(Loop*, LPPassManager&); + + virtual void getAnalysisUsage(AnalysisUsage&) const; + }; // class LoopDependenceAnalysis + + + // createLoopDependenceAnalysisPass - This creates an instance of the + // LoopDependenceAnalysis pass. + // + LoopPass *createLoopDependenceAnalysisPass(); + +} // namespace llvm + +#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */ diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index fb0b584..9e5f57e 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -281,6 +281,16 @@ public: } } + /// getUniqueExitBlock - If getUniqueExitBlocks would return exactly one + /// block, return that block. Otherwise return null. + BlockT *getUniqueExitBlock() const { + SmallVector<BlockT*, 8> UniqueExitBlocks; + getUniqueExitBlocks(UniqueExitBlocks); + if (UniqueExitBlocks.size() == 1) + return UniqueExitBlocks[0]; + return 0; + } + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop /// from outside of the loop. If this is the case, the block branching to the diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index ca41e51..7659b5b 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -34,9 +34,6 @@ public: // runOnLoop - This method should be implemented by the subclass to perform // whatever action is necessary for the specified Loop. virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0; - virtual bool runOnFunctionBody(Function &F, LPPassManager &LPM) { - return false; - } // Initialization and finalization hooks. virtual bool doInitialization(Loop *L, LPPassManager &LPM) { diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index d9121a8..35bd821 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -18,6 +18,7 @@ namespace llvm { class FunctionPass; class ImmutablePass; + class LoopPass; class ModulePass; class Pass; class LibCallInfo; @@ -116,6 +117,13 @@ namespace llvm { // createLiveValuesPass - This creates an instance of the LiveValues pass. // FunctionPass *createLiveValuesPass(); + + //===--------------------------------------------------------------------===// + // + // createLoopDependenceAnalysisPass - This creates an instance of the + // LoopDependenceAnalysis pass. + // + LoopPass *createLoopDependenceAnalysisPass(); // Minor pass prototypes, allowing us to expose them through bugpoint and // analyze. diff --git a/include/llvm/Analysis/ProfileInfoLoader.h b/include/llvm/Analysis/ProfileInfoLoader.h index 8a5141a..9076fbc 100644 --- a/include/llvm/Analysis/ProfileInfoLoader.h +++ b/include/llvm/Analysis/ProfileInfoLoader.h @@ -33,6 +33,7 @@ class ProfileInfoLoader { std::vector<unsigned> BlockCounts; std::vector<unsigned> EdgeCounts; std::vector<unsigned> BBTrace; + bool Warned; public: // ProfileInfoLoader ctor - Read the specified profiling data file, exiting // the program if the file is invalid or broken. diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 1c1298a..d699775 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -44,8 +44,8 @@ namespace llvm { class SCEVUnknown; /// SCEV - This class represents an analyzed expression in the program. These - /// are reference-counted opaque objects that the client is not allowed to - /// do much with directly. + /// are opaque objects that the client is not allowed to do much with + /// directly. /// class SCEV { const unsigned SCEVType; // The SCEV baseclass this node corresponds to @@ -82,6 +82,11 @@ namespace llvm { /// bool isOne() const; + /// isAllOnesValue - Return true if the expression is a constant + /// all-ones value. + /// + bool isAllOnesValue() const; + /// replaceSymbolicValuesWithConcrete - If this SCEV internally references /// the symbolic value "Sym", construct and return a new SCEV that produces /// the same value, but which uses the concrete value Conc instead of the @@ -300,8 +305,9 @@ namespace llvm { /// try to evaluate a few iterations of the loop until we get the exit /// condition gets a value of ExitWhen (true or false). If we cannot /// evaluate the trip count of the loop, return CouldNotCompute. - const SCEV* ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, - bool ExitWhen); + const SCEV* ComputeBackedgeTakenCountExhaustively(const Loop *L, + Value *Cond, + bool ExitWhen); /// HowFarToZero - Return the number of times a backedge comparing the /// specified value to zero will execute. If not computable, return @@ -329,6 +335,12 @@ namespace llvm { /// found. BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); + /// isNecessaryCond - Test whether the given CondValue value is a condition + /// which is at least as strict as the one described by Pred, LHS, and RHS. + bool isNecessaryCond(Value *Cond, ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS, + bool Inverse); + /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is /// in the header of its containing loop, we know the loop executes a /// constant number of times, and the PHI node is just a recurrence @@ -457,7 +469,7 @@ namespace llvm { /// widening. const SCEV* getTruncateOrNoop(const SCEV* V, const Type *Ty); - /// getIntegerSCEV - Given an integer or FP type, create a constant for the + /// getIntegerSCEV - Given a SCEVable type, create a constant for the /// specified signed integer value and return a SCEV for the constant. const SCEV* getIntegerSCEV(int Val, const Type *Ty); @@ -531,10 +543,11 @@ namespace llvm { /// is deleted. void forgetLoopBackedgeTakenCount(const Loop *L); - /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is - /// guaranteed to end in (at every loop iteration). It is, at the same time, - /// the minimum number of times S is divisible by 2. For example, given {4,+,8} - /// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S. + /// GetMinTrailingZeros - Determine the minimum number of zero bits that S + /// is guaranteed to end in (at every loop iteration). It is, at the same + /// time, the minimum number of times S is divisible by 2. For example, + /// given {4,+,8} it returns 2. If S is guaranteed to be 0, it returns the + /// bitwidth of S. uint32_t GetMinTrailingZeros(const SCEV* S); /// GetMinLeadingZeros - Determine the minimum number of zero bits that S is diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 730c97f..90dba8b 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -28,7 +28,8 @@ namespace llvm { /// memory. struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> { ScalarEvolution &SE; - std::map<const SCEV*, AssertingVH<Value> > InsertedExpressions; + std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > + InsertedExpressions; std::set<Value*> InsertedValues; BasicBlock::iterator InsertPt; @@ -43,48 +44,18 @@ namespace llvm { /// different places within the same BasicBlock can do so. void clear() { InsertedExpressions.clear(); } - /// isInsertedInstruction - Return true if the specified instruction was - /// inserted by the code rewriter. If so, the client should not modify the - /// instruction. - bool isInsertedInstruction(Instruction *I) const { - return InsertedValues.count(I); - } - - /// isInsertedExpression - Return true if the the code rewriter has a - /// Value* recorded for the given expression. - bool isInsertedExpression(const SCEV *S) const { - return InsertedExpressions.count(S); - } - /// getOrInsertCanonicalInductionVariable - This method returns the /// canonical induction variable of the specified type for the specified /// loop (inserting one if there is none). A canonical induction variable /// starts at zero and steps by one on each iteration. Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty); - /// addInsertedValue - Remember the specified instruction as being the - /// canonical form for the specified SCEV. - void addInsertedValue(Value *V, const SCEV *S) { - InsertedExpressions[S] = V; - InsertedValues.insert(V); - } - - void setInsertionPoint(BasicBlock::iterator NewIP) { InsertPt = NewIP; } - - BasicBlock::iterator getInsertionPoint() const { return InsertPt; } - - /// expandCodeFor - Insert code to directly compute the specified SCEV - /// expression into the program. The inserted code is inserted into the - /// SCEVExpander's current insertion point. If a type is specified, the - /// result will be expanded to have that type, with a cast if necessary. - Value *expandCodeFor(const SCEV* SH, const Type *Ty = 0); - /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. Value *expandCodeFor(const SCEV* SH, const Type *Ty, BasicBlock::iterator IP) { - setInsertionPoint(IP); + InsertPt = IP; return expandCodeFor(SH, Ty); } @@ -111,6 +82,19 @@ namespace llvm { Value *expand(const SCEV *S); + /// expandCodeFor - Insert code to directly compute the specified SCEV + /// expression into the program. The inserted code is inserted into the + /// SCEVExpander's current insertion point. If a type is specified, the + /// result will be expanded to have that type, with a cast if necessary. + Value *expandCodeFor(const SCEV* SH, const Type *Ty = 0); + + /// isInsertedInstruction - Return true if the specified instruction was + /// inserted by the code rewriter. If so, the client should not modify the + /// instruction. + bool isInsertedInstruction(Instruction *I) const { + return InsertedValues.count(I); + } + Value *visitConstant(const SCEVConstant *S) { return S->getValue(); } diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index a004632..f3ca306 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -33,6 +33,7 @@ namespace llvm { class GlobalVariable; class MachineConstantPoolEntry; class MachineConstantPoolValue; + class MachineModuleInfo; class DwarfWriter; class Mangler; class Section; @@ -58,14 +59,12 @@ namespace llvm { gcp_map_type GCMetadataPrinters; protected: - /// DW -This is needed because printDeclare() has to insert - /// DbgVariable entries into the dwarf table. This is a short term hack - /// that ought be fixed soon. + /// MMI - If available, this is a pointer to the current MachineModuleInfo. + MachineModuleInfo *MMI; + + /// DW - If available, this is a pointer to the current dwarf writer. DwarfWriter *DW; - // Necessary for external weak linkage support - std::set<const GlobalValue*> ExtWeakSymbols; - /// OptLevel - Generating code at a specific optimization level. CodeGenOpt::Level OptLevel; public: @@ -110,6 +109,15 @@ namespace llvm { /// bool VerboseAsm; + /// Private state for PrintSpecial() + // Assign a unique ID to this machine instruction. + mutable const MachineInstr *LastMI; + mutable const Function *LastFn; + mutable unsigned Counter; + + // Private state for processDebugLock() + mutable DebugLocTuple PrevDLT; + protected: explicit AsmPrinter(raw_ostream &o, TargetMachine &TM, const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V); diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h index 6628329..eefbc45 100644 --- a/include/llvm/CodeGen/IntrinsicLowering.h +++ b/include/llvm/CodeGen/IntrinsicLowering.h @@ -25,8 +25,12 @@ namespace llvm { class IntrinsicLowering { const TargetData& TD; + + + bool Warned; public: - explicit IntrinsicLowering(const TargetData &td) : TD(td) {} + explicit IntrinsicLowering(const TargetData &td) : + TD(td), Warned(false) {} /// AddPrototypes - This method, if called, causes all of the prototypes /// that might be needed by an intrinsic lowering implementation to be diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index d3a0995..3f30de5 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -74,8 +74,9 @@ public: return *this; } - const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB) const { - MI->addOperand(MachineOperand::CreateMBB(MBB)); + const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags)); return *this; } @@ -85,25 +86,29 @@ public: } const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx, - int Offset = 0) const { - MI->addOperand(MachineOperand::CreateCPI(Idx, Offset)); + int Offset = 0, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags)); return *this; } - const MachineInstrBuilder &addJumpTableIndex(unsigned Idx) const { - MI->addOperand(MachineOperand::CreateJTI(Idx)); + const MachineInstrBuilder &addJumpTableIndex(unsigned Idx, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags)); return *this; } const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV, - int64_t Offset = 0) const { - MI->addOperand(MachineOperand::CreateGA(GV, Offset)); + int64_t Offset = 0, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags)); return *this; } const MachineInstrBuilder &addExternalSymbol(const char *FnName, - int64_t Offset = 0) const { - MI->addOperand(MachineOperand::CreateES(FnName, Offset)); + int64_t Offset = 0, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateES(FnName, Offset, TargetFlags)); return *this; } @@ -113,28 +118,7 @@ public: } const MachineInstrBuilder &addOperand(const MachineOperand &MO) const { - if (MO.isReg()) - return addReg(MO.getReg(), - (MO.isDef() ? RegState::Define : 0) | - (MO.isImplicit() ? RegState::Implicit : 0) | - (MO.isKill() ? RegState::Kill : 0) | - (MO.isDead() ? RegState::Dead : 0) | - (MO.isEarlyClobber() ? RegState::EarlyClobber : 0), - MO.getSubReg()); - if (MO.isImm()) - return addImm(MO.getImm()); - if (MO.isFI()) - return addFrameIndex(MO.getIndex()); - if (MO.isGlobal()) - return addGlobalAddress(MO.getGlobal(), MO.getOffset()); - if (MO.isCPI()) - return addConstantPoolIndex(MO.getIndex(), MO.getOffset()); - if (MO.isSymbol()) - return addExternalSymbol(MO.getSymbolName()); - if (MO.isJTI()) - return addJumpTableIndex(MO.getIndex()); - - assert(0 && "Unknown operand for MachineInstrBuilder::AddOperand!"); + MI->addOperand(MO); return *this; } }; diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index ba538d7..5a7f76b 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -47,7 +47,14 @@ public: private: /// OpKind - Specify what kind of operand this is. This discriminates the /// union. - MachineOperandType OpKind : 8; + unsigned char OpKind; // MachineOperandType + + /// SubReg - Subregister number, only valid for MO_Register. A value of 0 + /// indicates the MO_Register has no subReg. + unsigned char SubReg; + + /// TargetFlags - This is a set of target-specific operand flags. + unsigned char TargetFlags; /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register /// operands. @@ -73,10 +80,6 @@ private: /// model the GCC inline asm '&' constraint modifier. bool IsEarlyClobber : 1; - /// SubReg - Subregister number, only valid for MO_Register. A value of 0 - /// indicates the MO_Register has no subReg. - unsigned char SubReg; - /// ParentMI - This is the instruction that this operand is embedded into. /// This is valid for all operand types, when the operand is in an instr. MachineInstr *ParentMI; @@ -105,7 +108,9 @@ private: } OffsetedInfo; } Contents; - explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {} + explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) { + TargetFlags = 0; + } public: MachineOperand(const MachineOperand &M) { *this = M; @@ -115,7 +120,12 @@ public: /// getType - Returns the MachineOperandType for this operand. /// - MachineOperandType getType() const { return OpKind; } + MachineOperandType getType() const { return (MachineOperandType)OpKind; } + + unsigned char getTargetFlags() const { return TargetFlags; } + void setTargetFlags(unsigned char F) { TargetFlags = F; } + void addTargetFlag(unsigned char F) { TargetFlags |= F; } + /// getParent - Return the instruction that this operand belongs to. /// @@ -361,9 +371,11 @@ public: Op.SubReg = SubReg; return Op; } - static MachineOperand CreateMBB(MachineBasicBlock *MBB) { + static MachineOperand CreateMBB(MachineBasicBlock *MBB, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_MachineBasicBlock); Op.setMBB(MBB); + Op.setTargetFlags(TargetFlags); return Op; } static MachineOperand CreateFI(unsigned Idx) { @@ -371,27 +383,35 @@ public: Op.setIndex(Idx); return Op; } - static MachineOperand CreateCPI(unsigned Idx, int Offset) { + static MachineOperand CreateCPI(unsigned Idx, int Offset, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_ConstantPoolIndex); Op.setIndex(Idx); Op.setOffset(Offset); + Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateJTI(unsigned Idx) { + static MachineOperand CreateJTI(unsigned Idx, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_JumpTableIndex); Op.setIndex(Idx); + Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset) { + static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_GlobalAddress); Op.Contents.OffsetedInfo.Val.GV = GV; Op.setOffset(Offset); + Op.setTargetFlags(TargetFlags); return Op; } - static MachineOperand CreateES(const char *SymName, int64_t Offset = 0) { + static MachineOperand CreateES(const char *SymName, int64_t Offset = 0, + unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_ExternalSymbol); Op.Contents.OffsetedInfo.Val.SymbolName = SymName; Op.setOffset(Offset); + Op.setTargetFlags(TargetFlags); return Op; } const MachineOperand &operator=(const MachineOperand &MO) { @@ -404,6 +424,7 @@ public: SubReg = MO.SubReg; ParentMI = MO.ParentMI; Contents = MO.Contents; + TargetFlags = MO.TargetFlags; return *this; } diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index ec2d1d7..bac3eec 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -278,31 +278,37 @@ public: return getConstantFP(Val, VT, true); } SDValue getGlobalAddress(const GlobalValue *GV, MVT VT, - int64_t offset = 0, bool isTargetGA = false); + int64_t offset = 0, bool isTargetGA = false, + unsigned char TargetFlags = 0); SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT, - int64_t offset = 0) { - return getGlobalAddress(GV, VT, offset, true); + int64_t offset = 0, + unsigned char TargetFlags = 0) { + return getGlobalAddress(GV, VT, offset, true, TargetFlags); } SDValue getFrameIndex(int FI, MVT VT, bool isTarget = false); SDValue getTargetFrameIndex(int FI, MVT VT) { return getFrameIndex(FI, VT, true); } - SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false); - SDValue getTargetJumpTable(int JTI, MVT VT) { - return getJumpTable(JTI, VT, true); + SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false, + unsigned char TargetFlags = 0); + SDValue getTargetJumpTable(int JTI, MVT VT, unsigned char TargetFlags = 0) { + return getJumpTable(JTI, VT, true, TargetFlags); } SDValue getConstantPool(Constant *C, MVT VT, - unsigned Align = 0, int Offs = 0, bool isT=false); + unsigned Align = 0, int Offs = 0, bool isT=false, + unsigned char TargetFlags = 0); SDValue getTargetConstantPool(Constant *C, MVT VT, - unsigned Align = 0, int Offset = 0) { - return getConstantPool(C, VT, Align, Offset, true); + unsigned Align = 0, int Offset = 0, + unsigned char TargetFlags = 0) { + return getConstantPool(C, VT, Align, Offset, true, TargetFlags); } SDValue getConstantPool(MachineConstantPoolValue *C, MVT VT, - unsigned Align = 0, int Offs = 0, bool isT=false); + unsigned Align = 0, int Offs = 0, bool isT=false, + unsigned char TargetFlags = 0); SDValue getTargetConstantPool(MachineConstantPoolValue *C, MVT VT, unsigned Align = 0, - int Offset = 0) { - return getConstantPool(C, VT, Align, Offset, true); + int Offset = 0, unsigned char TargetFlags=0) { + return getConstantPool(C, VT, Align, Offset, true, TargetFlags); } // When generating a branch to a BB, we don't in general know enough // to provide debug info for the BB at that time, so keep this one around. @@ -310,8 +316,8 @@ public: SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl); SDValue getExternalSymbol(const char *Sym, MVT VT); SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT); - SDValue getTargetExternalSymbol(const char *Sym, MVT VT); - SDValue getTargetExternalSymbol(const char *Sym, DebugLoc dl, MVT VT); + SDValue getTargetExternalSymbol(const char *Sym, MVT VT, + unsigned char TargetFlags = 0); SDValue getArgFlags(ISD::ArgFlagsTy Flags); SDValue getValueType(MVT); SDValue getRegister(unsigned Reg, MVT VT); @@ -862,7 +868,8 @@ private: std::vector<SDNode*> ValueTypeNodes; std::map<MVT, SDNode*, MVT::compareRawBits> ExtendedValueTypeNodes; StringMap<SDNode*> ExternalSymbols; - StringMap<SDNode*> TargetExternalSymbols; + + std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols; }; template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> { diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 1b6fecd..adf0478 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1819,13 +1819,15 @@ public: class GlobalAddressSDNode : public SDNode { GlobalValue *TheGlobal; int64_t Offset; + unsigned char TargetFlags; friend class SelectionDAG; - GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT VT, - int64_t o = 0); + GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA, MVT VT, + int64_t o, unsigned char TargetFlags); public: GlobalValue *getGlobal() const { return TheGlobal; } int64_t getOffset() const { return Offset; } + unsigned char getTargetFlags() const { return TargetFlags; } // Return the address space this GlobalAddress belongs to. unsigned getAddressSpace() const; @@ -1858,14 +1860,16 @@ public: class JumpTableSDNode : public SDNode { int JTI; + unsigned char TargetFlags; friend class SelectionDAG; - JumpTableSDNode(int jti, MVT VT, bool isTarg) + JumpTableSDNode(int jti, MVT VT, bool isTarg, unsigned char TF) : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, - DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti) { + DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) { } public: int getIndex() const { return JTI; } + unsigned char getTargetFlags() const { return TargetFlags; } static bool classof(const JumpTableSDNode *) { return true; } static bool classof(const SDNode *N) { @@ -1881,40 +1885,27 @@ class ConstantPoolSDNode : public SDNode { } Val; int Offset; // It's a MachineConstantPoolValue if top bit is set. unsigned Alignment; // Minimum alignment requirement of CP (not log2 value). + unsigned char TargetFlags; friend class SelectionDAG; - ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0) + ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align, + unsigned char TF) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, DebugLoc::getUnknownLoc(), - getSDVTList(VT)), Offset(o), Alignment(0) { + getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { assert((int)Offset >= 0 && "Offset is too large"); Val.ConstVal = c; } - ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align) - : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, - DebugLoc::getUnknownLoc(), - getSDVTList(VT)), Offset(o), Alignment(Align) { - assert((int)Offset >= 0 && "Offset is too large"); - Val.ConstVal = c; - } - ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, - MVT VT, int o=0) - : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, - DebugLoc::getUnknownLoc(), - getSDVTList(VT)), Offset(o), Alignment(0) { - assert((int)Offset >= 0 && "Offset is too large"); - Val.MachineCPVal = v; - Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1); - } ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, - MVT VT, int o, unsigned Align) + MVT VT, int o, unsigned Align, unsigned char TF) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, DebugLoc::getUnknownLoc(), - getSDVTList(VT)), Offset(o), Alignment(Align) { + getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { assert((int)Offset >= 0 && "Offset is too large"); Val.MachineCPVal = v; Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1); } public: + bool isMachineConstantPoolEntry() const { return (int)Offset < 0; @@ -1937,6 +1928,7 @@ public: // Return the alignment of this constant pool object, which is either 0 (for // default alignment) or the desired value. unsigned getAlignment() const { return Alignment; } + unsigned char getTargetFlags() const { return TargetFlags; } const Type *getType() const; @@ -2101,15 +2093,18 @@ public: class ExternalSymbolSDNode : public SDNode { const char *Symbol; + unsigned char TargetFlags; + friend class SelectionDAG; - ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT) + ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, MVT VT) : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, DebugLoc::getUnknownLoc(), - getSDVTList(VT)), Symbol(Sym) { + getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) { } public: const char *getSymbol() const { return Symbol; } + unsigned char getTargetFlags() const { return TargetFlags; } static bool classof(const ExternalSymbolSDNode *) { return true; } static bool classof(const SDNode *N) { diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 95c3a11..bf8b19c 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -1,3 +1,4 @@ + //===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===// // // The LLVM Compiler Infrastructure @@ -72,6 +73,12 @@ namespace llvm { LAST_VALUETYPE = 30, // This always remains at the end of the list. + // This is the current maximum for LAST_VALUETYPE. + // Affects ValueTypeActions in TargetLowering.h. + // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors + // This value must be a multiple of 32. + MAX_ALLOWED_VALUETYPE = 64, + // iPTRAny - An int value the size of the pointer of the current // target to any address space. This must only be used internal to // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR. diff --git a/include/llvm/CompilerDriver/BuiltinOptions.h b/include/llvm/CompilerDriver/BuiltinOptions.h new file mode 100644 index 0000000..492dffd --- /dev/null +++ b/include/llvm/CompilerDriver/BuiltinOptions.h @@ -0,0 +1,33 @@ +//===--- BuiltinOptions.h - The LLVM Compiler Driver ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declarations of all global command-line option variables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H +#define LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H + +#include "llvm/Support/CommandLine.h" + +#include <string> + +namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; } + +extern llvm::cl::list<std::string> InputFilenames; +extern llvm::cl::opt<std::string> OutputFilename; +extern llvm::cl::list<std::string> Languages; +extern llvm::cl::opt<bool> DryRun; +extern llvm::cl::opt<bool> VerboseMode; +extern llvm::cl::opt<bool> CheckGraph; +extern llvm::cl::opt<bool> WriteGraph; +extern llvm::cl::opt<bool> ViewGraph; +extern llvm::cl::opt<SaveTempsEnum::Values> SaveTemps; + +#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H diff --git a/include/llvm/CompilerDriver/ForceLinkage.h b/include/llvm/CompilerDriver/ForceLinkage.h new file mode 100644 index 0000000..58ea167 --- /dev/null +++ b/include/llvm/CompilerDriver/ForceLinkage.h @@ -0,0 +1,82 @@ +//===--- ForceLinkage.h - The LLVM Compiler Driver --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// A bit of preprocessor magic to force references to static libraries. Needed +// because plugin initialization is done via static variables. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H +#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H + +#include "llvm/CompilerDriver/ForceLinkageMacros.h" + +namespace llvmc { + +// Declare all ForceLinkage$(PluginName) functions. + +#ifdef LLVMC_BUILTIN_PLUGIN_1 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_1); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_2 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_2); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_3 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_3); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_4 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_4); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_5 + LLVMC_FORCE_LINKAGE_DECL(LLVMC_BUILTIN_PLUGIN_5); +#endif + +namespace force_linkage { + + struct LinkageForcer { + + LinkageForcer() { + +// Call all ForceLinkage$(PluginName) functions. +#ifdef LLVMC_BUILTIN_PLUGIN_1 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_1); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_2 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_2); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_3 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_3); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_4 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_4); +#endif + +#ifdef LLVMC_BUILTIN_PLUGIN_5 + LLVMC_FORCE_LINKAGE_CALL(LLVMC_BUILTIN_PLUGIN_5); +#endif + + } + }; +} // End namespace force_linkage. + +// The only externally used bit. +void ForceLinkage() { + force_linkage::LinkageForcer dummy; +} + +} // End namespace llvmc. + +#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_H diff --git a/include/llvm/CompilerDriver/ForceLinkageMacros.h b/include/llvm/CompilerDriver/ForceLinkageMacros.h new file mode 100644 index 0000000..8862b00 --- /dev/null +++ b/include/llvm/CompilerDriver/ForceLinkageMacros.h @@ -0,0 +1,29 @@ +//===--- ForceLinkageMacros.h - The LLVM Compiler Driver --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open +// Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Preprocessor magic that forces references to static libraries - common +// macros used by both driver and plugins. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H +#define LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H + +#define LLVMC_FORCE_LINKAGE_PREFIX(PluginName) ForceLinkage ## PluginName + +#define LLVMC_FORCE_LINKAGE_FUN(PluginName) \ + LLVMC_FORCE_LINKAGE_PREFIX(PluginName) + +#define LLVMC_FORCE_LINKAGE_DECL(PluginName) \ + void LLVMC_FORCE_LINKAGE_FUN(PluginName) () + +#define LLVMC_FORCE_LINKAGE_CALL(PluginName) \ + LLVMC_FORCE_LINKAGE_FUN(PluginName) () + +#endif // LLVM_INCLUDE_COMPILER_DRIVER_FORCE_LINKAGE_MACROS_H diff --git a/include/llvm/CompilerDriver/Main.inc b/include/llvm/CompilerDriver/Main.inc index 2d50c95..4a83d56 100644 --- a/include/llvm/CompilerDriver/Main.inc +++ b/include/llvm/CompilerDriver/Main.inc @@ -12,15 +12,15 @@ // supported please refer to the tools' manual page or run the tool // with the --help option. // -// This -// //===----------------------------------------------------------------------===// #ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC #define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC +#include "llvm/CompilerDriver/BuiltinOptions.h" #include "llvm/CompilerDriver/CompilationGraph.h" #include "llvm/CompilerDriver/Error.h" +#include "llvm/CompilerDriver/ForceLinkage.h" #include "llvm/CompilerDriver/Plugin.h" #include "llvm/System/Path.h" @@ -59,27 +59,56 @@ cl::opt<bool> WriteGraph("write-graph", cl::opt<bool> ViewGraph("view-graph", cl::desc("Show compilation graph in GhostView"), cl::Hidden); -cl::opt<bool> SaveTemps("save-temps", - cl::desc("Keep temporary files"), - cl::Hidden); + +cl::opt<SaveTempsEnum::Values> SaveTemps +("save-temps", cl::desc("Keep temporary files"), + cl::init(SaveTempsEnum::Unset), + cl::values(clEnumValN(SaveTempsEnum::Obj, "obj", + "Save files in the directory specified with -o"), + clEnumValN(SaveTempsEnum::Cwd, "cwd", + "Use current working directory"), + clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"), + clEnumValEnd), + cl::ValueOptional); namespace { + + sys::Path getTempDir() { + sys::Path tempDir; + + // GCC 4.5-style -save-temps handling. + if (SaveTemps == SaveTempsEnum::Unset) { + tempDir = sys::Path::GetTemporaryDirectory(); + } + else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) { + tempDir = OutputFilename; + + if (!tempDir.exists()) { + std::string ErrMsg; + if (tempDir.createDirectoryOnDisk(true, &ErrMsg)) + throw std::runtime_error(ErrMsg); + } + } + // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty) + + return tempDir; + } + /// BuildTargets - A small wrapper for CompilationGraph::Build. int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) { int ret; - const sys::Path& tempDir = SaveTemps - ? sys::Path("") - : sys::Path(sys::Path::GetTemporaryDirectory()); + const sys::Path& tempDir = getTempDir(); try { ret = graph.Build(tempDir, langMap); } catch(...) { - tempDir.eraseFromDisk(true); + if (SaveTemps == SaveTempsEnum::Unset) + tempDir.eraseFromDisk(true); throw; } - if (!SaveTemps) + if (SaveTemps == SaveTempsEnum::Unset) tempDir.eraseFromDisk(true); return ret; } @@ -87,6 +116,8 @@ namespace { int main(int argc, char** argv) { try { + ForceLinkage(); + LanguageMap langMap; CompilationGraph graph; diff --git a/include/llvm/Config/Targets.def.in b/include/llvm/Config/Targets.def.in index a388472..d589ece 100644 --- a/include/llvm/Config/Targets.def.in +++ b/include/llvm/Config/Targets.def.in @@ -1,23 +1,23 @@ -//===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file enumerates all of the target architectures supported by -// this build of LLVM. Clients of this file should define the -// LLVM_TARGET macro to be a function-like macro with a single -// parameter (the name of the target); including this file will then -// enumerate all of the targets. -// -// The set of targets supported by LLVM is generated at configuration -// time, at which point this header is generated. Do not modify this -// header directly. -// -//===----------------------------------------------------------------------===// +/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file enumerates all of the target architectures supported by *| +|* this build of LLVM. Clients of this file should define the *| +|* LLVM_TARGET macro to be a function-like macro with a single *| +|* parameter (the name of the target); including this file will then *| +|* enumerate all of the targets. *| +|* *| +|* The set of targets supported by LLVM is generated at configuration *| +|* time, at which point this header is generated. Do not modify this *| +|* header directly. *| +|* *| +\*===----------------------------------------------------------------------===*/ #ifndef LLVM_TARGET # error Please define the macro LLVM_TARGET(TargetName) diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 4356e7d..27ef440 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -282,6 +282,12 @@ /* Have pthread_mutex_lock */ #cmakedefine HAVE_PTHREAD_MUTEX_LOCK ${HAVE_PTHREAD_MUTEX_LOCK} +/* Have pthread_rwlock_init */ +#cmakedefine HAVE_PTHREAD_RWLOCK_INIT ${HAVE_PTHREAD_RWLOCK_INIT} + +/* Have pthread_getspecific */ +#cmakedefine HAVE_PTHREAD_GETSPECIFIC ${HAVE_PTHREAD_GETSPECIFIC} + /* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */ #undef HAVE_RAND48 diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index ac60f4d..9452ce7 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -279,6 +279,9 @@ /* Define to have the %a format string */ #undef HAVE_PRINTF_A +/* Have pthread_getspecific */ +#undef HAVE_PTHREAD_GETSPECIFIC + /* Define to 1 if you have the <pthread.h> header file. */ #undef HAVE_PTHREAD_H diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 52fff20..da69d25 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -865,6 +865,7 @@ public: /// get() - Static factory methods - Return objects of the specified value. /// static MDString *get(const char *StrBegin, const char *StrEnd); + static MDString *get(const std::string &Str); /// size() - The length of this string. /// diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 170e184..613adb5 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -29,13 +29,14 @@ class Constant; class Function; class GlobalVariable; class GlobalValue; +class JITEventListener; +class JITMemoryManager; +class MachineCodeInfo; class Module; class ModuleProvider; +class MutexGuard; class TargetData; class Type; -class MutexGuard; -class JITMemoryManager; -class MachineCodeInfo; class ExecutionEngineState { private: @@ -276,7 +277,14 @@ public: virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) { return getPointerToGlobal((GlobalValue*)GV); } - + + /// Registers a listener to be called back on various events within + /// the JIT. See JITEventListener.h for more details. Does not + /// take ownership of the argument. The argument may be NULL, in + /// which case these functions do nothing. + virtual void RegisterJITEventListener(JITEventListener *L) {} + virtual void UnregisterJITEventListener(JITEventListener *L) {} + /// DisableLazyCompilation - If called, the JIT will abort if lazy compilation /// is ever attempted. void DisableLazyCompilation(bool Disabled = true) { diff --git a/include/llvm/ExecutionEngine/Interpreter.h b/include/llvm/ExecutionEngine/Interpreter.h index b2b0464..7425cdb 100644 --- a/include/llvm/ExecutionEngine/Interpreter.h +++ b/include/llvm/ExecutionEngine/Interpreter.h @@ -18,9 +18,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include <cstdlib> -namespace llvm { - extern void LinkInInterpreter(); -} +extern "C" void LLVMLinkInInterpreter(); namespace { struct ForceInterpreterLinking { @@ -32,7 +30,7 @@ namespace { if (std::getenv("bar") != (char*) -1) return; - llvm::LinkInInterpreter(); + LLVMLinkInInterpreter(); } } ForceInterpreterLinking; } diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h index d4d1e73..6013db4 100644 --- a/include/llvm/ExecutionEngine/JIT.h +++ b/include/llvm/ExecutionEngine/JIT.h @@ -18,9 +18,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include <cstdlib> -namespace llvm { - extern void LinkInJIT(); -} +extern "C" void LLVMLinkInJIT(); namespace { struct ForceJITLinking { @@ -32,7 +30,7 @@ namespace { if (std::getenv("bar") != (char*) -1) return; - llvm::LinkInJIT(); + LLVMLinkInJIT(); } } ForceJITLinking; } diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h new file mode 100644 index 0000000..dd76f26 --- /dev/null +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -0,0 +1,59 @@ +//===- JITEventListener.h - Exposes events from JIT compilation -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the JITEventListener interface, which lets users get +// callbacks when significant events happen during the JIT compilation process. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H +#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class Function; + +/// Empty for now, but this object will contain all details about the +/// generated machine code that a Listener might care about. +struct JITEvent_EmittedFunctionDetails { +}; + +/// JITEventListener - This interface is used by the JIT to notify clients about +/// significant events during compilation. For example, we could have +/// implementations for profilers and debuggers that need to know where +/// functions have been emitted. +/// +/// Each method defaults to doing nothing, so you only need to override the ones +/// you care about. +class JITEventListener { +public: + JITEventListener() {} + virtual ~JITEventListener(); // Defined in JIT.cpp. + + typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails; + /// NotifyFunctionEmitted - Called after a function has been successfully + /// emitted to memory. The function still has its MachineFunction attached, + /// if you should happen to need that. + virtual void NotifyFunctionEmitted(const Function &F, + void *Code, size_t Size, + const EmittedFunctionDetails &Details) {} + + /// NotifyFreeingMachineCode - This is called inside of + /// freeMachineCodeForFunction(), after the global mapping is removed, but + /// before the machine code is returned to the allocator. OldPtr is the + /// address of the machine code. + virtual void NotifyFreeingMachineCode(const Function &F, void *OldPtr) {} +}; + +JITEventListener *createMacOSJITEventListener(); + +} // end namespace llvm. + +#endif diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td index a73dc45..4723ffb 100644 --- a/include/llvm/IntrinsicsARM.td +++ b/include/llvm/IntrinsicsARM.td @@ -302,15 +302,24 @@ let TargetPrefix = "arm" in { // Interleaving vector stores from N-element structures. def int_arm_neon_vst3i : Intrinsic<[llvm_void_ty], - [llvm_anyint_ty, llvm_ptr_ty], + [llvm_ptr_ty, llvm_anyint_ty], [IntrWriteArgMem]>; def int_arm_neon_vst3f : Intrinsic<[llvm_void_ty], - [llvm_anyfloat_ty, llvm_ptr_ty], + [llvm_ptr_ty, llvm_anyfloat_ty], [IntrWriteArgMem]>; def int_arm_neon_vst4i : Intrinsic<[llvm_void_ty], - [llvm_anyint_ty, llvm_ptr_ty], + [llvm_ptr_ty, llvm_anyint_ty], [IntrWriteArgMem]>; def int_arm_neon_vst4f : Intrinsic<[llvm_void_ty], - [llvm_anyfloat_ty, llvm_ptr_ty], + [llvm_ptr_ty, llvm_anyfloat_ty], [IntrWriteArgMem]>; + + // Vector Table Lookup + def int_arm_neon_vtbl : Intrinsic<[llvm_v8i8_ty], + [llvm_anyint_ty, llvm_v8i8_ty], + [IntrNoMem]>; + // Vector Table Extension + def int_arm_neon_vtbx : Intrinsic<[llvm_v8i8_ty], + [llvm_v8i8_ty, llvm_anyint_ty, + llvm_v8i8_ty], [IntrNoMem]>; } diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 0fb837d..22d6aeb 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -77,6 +77,7 @@ namespace { (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLiveValuesPass(); + (void) llvm::createLoopDependenceAnalysisPass(); (void) llvm::createLoopExtractorPass(); (void) llvm::createLoopSimplifyPass(); (void) llvm::createLoopStrengthReducePass(); diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h new file mode 100644 index 0000000..13180e8 --- /dev/null +++ b/include/llvm/MC/MCContext.h @@ -0,0 +1,166 @@ +//===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCCONTEXT_H +#define LLVM_MC_MCCONTEXT_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Allocator.h" + +namespace llvm { + class MCValue; + class MCSection; + class MCSymbol; + + /// MCContext - Context object for machine code objects. + class MCContext { + MCContext(const MCContext&); // DO NOT IMPLEMENT + MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT + + /// Sections - Bindings of names to allocated sections. + StringMap<MCSection*> Sections; + + /// Symbols - Bindings of names to symbols. + StringMap<MCSymbol*> Symbols; + + /// SymbolValues - Bindings of symbols to values. + DenseMap<MCSymbol*, MCValue> SymbolValues; + + /// Allocator - Allocator object used for creating machine code objects. + /// + /// We use a bump pointer allocator to avoid the need to track all allocated + /// objects. + BumpPtrAllocator Allocator; + + public: + MCContext(); + ~MCContext(); + + /// GetSection - Get or create a new section with the given @param Name. + MCSection *GetSection(const char *Name); + + /// CreateSymbol - Create a new symbol with the specified @param Name. + /// + /// @param Name - The symbol name, which must be unique across all symbols. + MCSymbol *CreateSymbol(const char *Name); + + /// GetOrCreateSymbol - Lookup the symbol inside with the specified + /// @param Name. If it exists, return it. If not, create a forward + /// reference and return it. + /// + /// @param Name - The symbol name, which must be unique across all symbols. + MCSymbol *GetOrCreateSymbol(const char *Name); + + /// CreateTemporarySymbol - Create a new temporary symbol with the specified + /// @param Name. + /// + /// @param Name - The symbol name, for debugging purposes only, temporary + /// symbols do not surive assembly. If non-empty the name must be unique + /// across all symbols. + MCSymbol *CreateTemporarySymbol(const char *Name = ""); + + /// LookupSymbol - Get the symbol for @param Name, or null. + MCSymbol *LookupSymbol(const char *Name) const; + + /// ClearSymbolValue - Erase a value binding for @param Symbol, if one + /// exists. + void ClearSymbolValue(MCSymbol *Symbol); + + /// SetSymbolValue - Set the value binding for @param Symbol to @param + /// Value. + void SetSymbolValue(MCSymbol *Symbol, const MCValue &Value); + + /// GetSymbolValue - Return the current value for @param Symbol, or null if + /// none exists. + const MCValue *GetSymbolValue(MCSymbol *Symbol) const; + + void *Allocate(unsigned Size, unsigned Align = 8) { + return Allocator.Allocate(Size, Align); + } + void Deallocate(void *Ptr) { + } + }; + +} // end namespace llvm + +// operator new and delete aren't allowed inside namespaces. +// The throw specifications are mandated by the standard. +/// @brief Placement new for using the MCContext's allocator. +/// +/// This placement form of operator new uses the MCContext's allocator for +/// obtaining memory. It is a non-throwing new, which means that it returns +/// null on error. (If that is what the allocator does. The current does, so if +/// this ever changes, this operator will have to be changed, too.) +/// Usage looks like this (assuming there's an MCContext 'Context' in scope): +/// @code +/// // Default alignment (16) +/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); +/// // Specific alignment +/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments); +/// @endcode +/// Please note that you cannot use delete on the pointer; it must be +/// deallocated using an explicit destructor call followed by +/// @c Context.Deallocate(Ptr). +/// +/// @param Bytes The number of bytes to allocate. Calculated by the compiler. +/// @param C The MCContext that provides the allocator. +/// @param Alignment The alignment of the allocated memory (if the underlying +/// allocator supports it). +/// @return The allocated memory. Could be NULL. +inline void *operator new(size_t Bytes, llvm::MCContext &C, + size_t Alignment = 16) throw () { + return C.Allocate(Bytes, Alignment); +} +/// @brief Placement delete companion to the new above. +/// +/// This operator is just a companion to the new above. There is no way of +/// invoking it directly; see the new operator for more details. This operator +/// is called implicitly by the compiler if a placement new expression using +/// the MCContext throws in the object constructor. +inline void operator delete(void *Ptr, llvm::MCContext &C, size_t) + throw () { + C.Deallocate(Ptr); +} + +/// This placement form of operator new[] uses the MCContext's allocator for +/// obtaining memory. It is a non-throwing new[], which means that it returns +/// null on error. +/// Usage looks like this (assuming there's an MCContext 'Context' in scope): +/// @code +/// // Default alignment (16) +/// char *data = new (Context) char[10]; +/// // Specific alignment +/// char *data = new (Context, 8) char[10]; +/// @endcode +/// Please note that you cannot use delete on the pointer; it must be +/// deallocated using an explicit destructor call followed by +/// @c Context.Deallocate(Ptr). +/// +/// @param Bytes The number of bytes to allocate. Calculated by the compiler. +/// @param C The MCContext that provides the allocator. +/// @param Alignment The alignment of the allocated memory (if the underlying +/// allocator supports it). +/// @return The allocated memory. Could be NULL. +inline void *operator new[](size_t Bytes, llvm::MCContext& C, + size_t Alignment = 16) throw () { + return C.Allocate(Bytes, Alignment); +} + +/// @brief Placement delete[] companion to the new[] above. +/// +/// This operator is just a companion to the new[] above. There is no way of +/// invoking it directly; see the new[] operator for more details. This operator +/// is called implicitly by the compiler if a placement new[] expression using +/// the MCContext throws in the object constructor. +inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () { + C.Deallocate(Ptr); +} + +#endif diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 457c2ae..3108985 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -16,7 +16,7 @@ #ifndef LLVM_MC_MCINST_H #define LLVM_MC_MCINST_H -#include "llvm/MC/MCImm.h" +#include "llvm/MC/MCValue.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" @@ -31,14 +31,14 @@ class MCOperand { kRegister, ///< Register operand. kImmediate, ///< Immediate operand. kMBBLabel, ///< Basic block label. - kMCImm + kMCValue }; unsigned char Kind; union { unsigned RegVal; int64_t ImmVal; - MCImm MCImmVal; + MCValue MCValueVal; struct { unsigned FunctionNo; unsigned BlockNo; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h new file mode 100644 index 0000000..341f7f0 --- /dev/null +++ b/include/llvm/MC/MCSection.h @@ -0,0 +1,28 @@ +//===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSECTION_H +#define LLVM_MC_MCSECTION_H + +#include <string> + +namespace llvm { + + class MCSection { + std::string Name; + + public: + MCSection(const char *_Name) : Name(_Name) {} + + const std::string &getName() const { return Name; } + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h new file mode 100644 index 0000000..bb85d2d --- /dev/null +++ b/include/llvm/MC/MCStreamer.h @@ -0,0 +1,191 @@ +//===- MCStreamer.h - High-level Streaming Machine Code Output --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSTREAMER_H +#define LLVM_MC_MCSTREAMER_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + class MCContext; + class MCValue; + class MCInst; + class MCSection; + class MCSymbol; + class raw_ostream; + + /// MCStreamer - Streaming machine code generation interface. + class MCStreamer { + public: + enum SymbolAttr { + Global, /// .globl + Hidden, /// .hidden (ELF) + IndirectSymbol, /// .indirect_symbol (Apple) + Internal, /// .internal (ELF) + LazyReference, /// .lazy_reference (Apple) + NoDeadStrip, /// .no_dead_strip (Apple) + PrivateExtern, /// .private_extern (Apple) + Protected, /// .protected (ELF) + Reference, /// .reference (Apple) + Weak, /// .weak + WeakDefinition, /// .weak_definition (Apple) + WeakReference, /// .weak_reference (Apple) + + SymbolAttrFirst = Global, + SymbolAttrLast = WeakReference + }; + + private: + MCContext &Context; + + MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT + MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT + + protected: + MCStreamer(MCContext &Ctx); + + public: + virtual ~MCStreamer(); + + MCContext &getContext() const { return Context; } + + /// @name Symbol & Section Management + /// @{ + + /// SwitchSection - Set the current section where code is being emitted to + /// @param Section. + /// + /// This corresponds to assembler directives like .section, .text, etc. + virtual void SwitchSection(MCSection *Section) = 0; + + /// EmitLabel - Emit a label for @param Symbol into the current section. + /// + /// This corresponds to an assembler statement such as: + /// foo: + /// + /// @param Symbol - The symbol to emit. A given symbol should only be + /// emitted as a label once, and symbols emitted as a label should never be + /// used in an assignment. + // + // FIXME: What to do about the current section? Should we get rid of the + // symbol section in the constructor and initialize it here? + virtual void EmitLabel(MCSymbol *Symbol) = 0; + + /// EmitAssignment - Emit an assignment of @param Value to @param Symbol. + /// + /// This corresponds to an assembler statement such as: + /// symbol = value + /// + /// The assignment generates no code, but has the side effect of binding the + /// value in the current context. For the assembly streamer, this prints the + /// binding into the .s file. + /// + /// @param Symbol - The symbol being assigned to. + /// @param Value - The value for the symbol. + /// @param MakeAbsolute - If true, then the symbol should be given the + /// absolute value of @param Value, even if @param Value would be + /// relocatable expression. This corresponds to the ".set" directive. + virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value, + bool MakeAbsolute = false) = 0; + + /// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol. + // + // FIXME: This doesn't make much sense, could we just have attributes be on + // the symbol and make the printer smart enough to add the right symbols? + // This should work as long as the order of attributes in the file doesn't + // matter. + virtual void EmitSymbolAttribute(MCSymbol *Symbol, + SymbolAttr Attribute) = 0; + + /// @} + /// @name Generating Data + /// @{ + + /// EmitBytes - Emit @param Length bytes starting at @param Data into the + /// output. + /// + /// This is used to implement assembler directives such as .byte, .ascii, + /// etc. + virtual void EmitBytes(const char *Data, unsigned Length) = 0; + + /// EmitValue - Emit the expression @param Value into the output as a native + /// integer of the given @param Size bytes. + /// + /// This is used to implement assembler directives such as .word, .quad, + /// etc. + /// + /// @param Value - The value to emit. + /// @param Size - The size of the integer (in bytes) to emit. This must + /// match a native machine width. + virtual void EmitValue(const MCValue &Value, unsigned Size) = 0; + + /// EmitValueToAlignment - Emit some number of copies of @param Value until + /// the byte alignment @param ByteAlignment is reached. + /// + /// If the number of bytes need to emit for the alignment is not a multiple + /// of @param ValueSize, then the contents of the emitted fill bytes is + /// undefined. + /// + /// This used to implement the .align assembler directive. + /// + /// @param ByteAlignment - The alignment to reach. This must be a power of + /// two. + /// @param Value - The value to use when filling bytes. + /// @param Size - The size of the integer (in bytes) to emit for @param + /// Value. This must match a native machine width. + /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If + /// the alignment cannot be reached in this many bytes, no bytes are + /// emitted. + virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0) = 0; + + /// EmitValueToOffset - Emit some number of copies of @param Value until the + /// byte offset @param Offset is reached. + /// + /// This is used to implement assembler directives such as .org. + /// + /// @param Offset - The offset to reach.This may be an expression, but the + /// expression must be associated with the current section. + /// @param Value - The value to use when filling bytes. + // + // FIXME: How are we going to signal failures out of this? + virtual void EmitValueToOffset(const MCValue &Offset, + unsigned char Value = 0) = 0; + + /// @} + + /// EmitInstruction - Emit the given @param Instruction into the current + /// section. + virtual void EmitInstruction(const MCInst &Inst) = 0; + + /// Finish - Finish emission of machine code and flush any output. + virtual void Finish() = 0; + }; + + /// createAsmStreamer - Create a machine code streamer which will print out + /// assembly for the native target, suitable for compiling with a native + /// assembler. + MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS); + + // FIXME: These two may end up getting rolled into a single + // createObjectStreamer interface, which implements the assembler backend, and + // is parameterized on an output object file writer. + + /// createMachOStream - Create a machine code streamer which will generative + /// Mach-O format object files. + MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS); + + /// createELFStreamer - Create a machine code streamer which will generative + /// ELF format object files. + MCStreamer *createELFStreamer(MCContext &Ctx, raw_ostream &OS); + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h new file mode 100644 index 0000000..06f50ae --- /dev/null +++ b/include/llvm/MC/MCSymbol.h @@ -0,0 +1,33 @@ +//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSYMBOL_H +#define LLVM_MC_MCSYMBOL_H + +#include <string> + +namespace llvm { + class MCSymbol { + MCSection *Section; + std::string Name; + unsigned IsTemporary : 1; + + public: + MCSymbol(const char *_Name, bool _IsTemporary) + : Section(0), Name(_Name), IsTemporary(_IsTemporary) {} + + MCSection *getSection() const { return Section; } + void setSection(MCSection *Value) { Section = Value; } + + const std::string &getName() const { return Name; } + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCImm.h b/include/llvm/MC/MCValue.h index 5b1efd8..7df12da 100644 --- a/include/llvm/MC/MCImm.h +++ b/include/llvm/MC/MCValue.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/MCImm.h - MCImm class ---------------------------*- C++ -*-===// +//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,25 @@ // //===----------------------------------------------------------------------===// // -// This file contains the declaration of the MCInst and MCOperand classes, which -// is the basic representation used to represent low-level machine code -// instructions. +// This file contains the declaration of the MCValue class. // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCIMM_H -#define LLVM_MC_MCIMM_H +#ifndef LLVM_MC_MCVALUE_H +#define LLVM_MC_MCVALUE_H + +#include "llvm/Support/DataTypes.h" namespace llvm { class MCSymbol; -/// MCImm - This represents an "assembler immediate". In its most general form, -/// this can hold "SymbolA - SymbolB + imm64". Not all targets supports +/// MCValue - This represents an "assembler immediate". In its most general +/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports /// relocations of this general form, but we need to represent this anyway. -class MCImm { +/// +/// Note that this class must remain a simple POD value class, because we need +/// it to live in unions etc. +class MCValue { MCSymbol *SymA, *SymB; int64_t Cst; public: @@ -32,16 +35,16 @@ public: MCSymbol *getSymB() const { return SymB; } - static MCImm get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) { - MCImm R; + static MCValue get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) { + MCValue R; R.Cst = Val; R.SymA = SymA; R.SymB = SymB; return R; } - static MCImm get(int64_t Val) { - MCImm R; + static MCValue get(int64_t Val) { + MCValue R; R.Cst = Val; R.SymA = 0; R.SymB = 0; diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h index 7a61b2b..080297f 100644 --- a/include/llvm/Support/DOTGraphTraits.h +++ b/include/llvm/Support/DOTGraphTraits.h @@ -51,7 +51,8 @@ struct DefaultDOTGraphTraits { /// getNodeLabel - Given a node and a pointer to the top level graph, return /// the label to print in the node. template<typename GraphType> - static std::string getNodeLabel(const void *Node, const GraphType& Graph) { + static std::string getNodeLabel(const void *Node, + const GraphType& Graph, bool ShortNames) { return ""; } diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index ca28aafa..01b44d0 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -72,6 +72,7 @@ template<typename GraphType> class GraphWriter { std::ostream &O; const GraphType &G; + bool ShortNames; typedef DOTGraphTraits<GraphType> DOTTraits; typedef GraphTraits<GraphType> GTraits; @@ -79,7 +80,8 @@ class GraphWriter { typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; public: - GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {} + GraphWriter(std::ostream &o, const GraphType &g, bool SN) : + O(o), G(g), ShortNames(SN) {} void writeHeader(const std::string &Name) { std::string GraphName = DOTTraits::getGraphName(G); @@ -130,7 +132,7 @@ public: O << "label=\"{"; if (!DOTTraits::renderGraphFromBottomUp()) { - O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); + O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames)); // If we should include the address of the node in the label, do so now. if (DOTTraits::hasNodeAddressLabel(Node, G)) @@ -156,7 +158,7 @@ public: } if (DOTTraits::renderGraphFromBottomUp()) { - O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G)); + O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G, ShortNames)); // If we should include the address of the node in the label, do so now. if (DOTTraits::hasNodeAddressLabel(Node, G)) @@ -250,10 +252,11 @@ public: template<typename GraphType> std::ostream &WriteGraph(std::ostream &O, const GraphType &G, + bool ShortNames = false, const std::string &Name = "", const std::string &Title = "") { // Start the graph emission process... - GraphWriter<GraphType> W(O, G); + GraphWriter<GraphType> W(O, G, ShortNames); // Output the header for the graph... W.writeHeader(Title); @@ -272,6 +275,7 @@ std::ostream &WriteGraph(std::ostream &O, const GraphType &G, template<typename GraphType> sys::Path WriteGraph(const GraphType &G, const std::string& Name, + bool ShortNames = false, const std::string& Title = "") { std::string ErrMsg; sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg); @@ -290,7 +294,7 @@ sys::Path WriteGraph(const GraphType &G, std::ofstream O(Filename.c_str()); if (O.good()) { - WriteGraph(O, G, Name, Title); + WriteGraph(O, G, ShortNames, Name, Title); cerr << " done. \n"; O.close(); @@ -308,8 +312,9 @@ sys::Path WriteGraph(const GraphType &G, template<typename GraphType> void ViewGraph(const GraphType& G, const std::string& Name, + bool ShortNames = false, const std::string& Title = "") { - sys::Path Filename = WriteGraph(G, Name, Title); + sys::Path Filename = WriteGraph(G, Name, ShortNames, Title); if (Filename.isEmpty()) { return; diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h index f34fc95..71b7ee5 100644 --- a/include/llvm/Support/Timer.h +++ b/include/llvm/Support/Timer.h @@ -16,6 +16,7 @@ #define LLVM_SUPPORT_TIMER_H #include "llvm/Support/DataTypes.h" +#include "llvm/System/Mutex.h" #include <string> #include <vector> #include <iosfwd> @@ -34,28 +35,37 @@ class TimerGroup; /// if they are never started. /// class Timer { - int64_t Elapsed; // Wall clock time elapsed in seconds - int64_t UserTime; // User time elapsed - int64_t SystemTime; // System time elapsed - int64_t MemUsed; // Memory allocated (in bytes) - int64_t PeakMem; // Peak memory used - int64_t PeakMemBase; // Temporary for peak calculation... + double Elapsed; // Wall clock time elapsed in seconds + double UserTime; // User time elapsed + double SystemTime; // System time elapsed + ssize_t MemUsed; // Memory allocated (in bytes) + size_t PeakMem; // Peak memory used + size_t PeakMemBase; // Temporary for peak calculation... std::string Name; // The name of this time variable bool Started; // Has this time variable ever been started? TimerGroup *TG; // The TimerGroup this Timer is in. + mutable sys::SmartMutex<true> Lock; // Mutex for the contents of this Timer. public: explicit Timer(const std::string &N); Timer(const std::string &N, TimerGroup &tg); Timer(const Timer &T); ~Timer(); - int64_t getProcessTime() const { return UserTime+SystemTime; } - int64_t getWallTime() const { return Elapsed; } - int64_t getMemUsed() const { return MemUsed; } - int64_t getPeakMem() const { return PeakMem; } + double getProcessTime() const { return UserTime+SystemTime; } + double getWallTime() const { return Elapsed; } + ssize_t getMemUsed() const { return MemUsed; } + size_t getPeakMem() const { return PeakMem; } std::string getName() const { return Name; } const Timer &operator=(const Timer &T) { + if (&T < this) { + T.Lock.acquire(); + Lock.acquire(); + } else { + Lock.acquire(); + T.Lock.acquire(); + } + Elapsed = T.Elapsed; UserTime = T.UserTime; SystemTime = T.SystemTime; @@ -65,6 +75,15 @@ public: Name = T.Name; Started = T.Started; assert(TG == T.TG && "Can only assign timers in the same TimerGroup!"); + + if (&T < this) { + T.Lock.release(); + Lock.release(); + } else { + Lock.release(); + T.Lock.release(); + } + return *this; } @@ -160,11 +179,9 @@ public: private: friend class Timer; - void addTimer() { ++NumTimers; } + void addTimer(); void removeTimer(); - void addTimerToPrint(const Timer &T) { - TimersToPrint.push_back(Timer(true, T)); - } + void addTimerToPrint(const Timer &T); }; } // End llvm namespace diff --git a/include/llvm/System/Atomic.h b/include/llvm/System/Atomic.h index c0612f9..4ec117b 100644 --- a/include/llvm/System/Atomic.h +++ b/include/llvm/System/Atomic.h @@ -20,14 +20,15 @@ namespace llvm { namespace sys { void MemoryFence(); - uint32_t CompareAndSwap32(volatile uint32_t* ptr, - uint32_t new_value, - uint32_t old_value); - int32_t AtomicIncrement32(volatile int32_t* ptr); - int32_t AtomicDecrement32(volatile int32_t* ptr); - int32_t AtomicAdd32(volatile int32_t* ptr, int32_t val); - - int64_t AtomicAdd64(volatile int64_t* ptr, int64_t val); + typedef uint32_t cas_flag; + cas_flag CompareAndSwap(volatile cas_flag* ptr, + cas_flag new_value, + cas_flag old_value); + cas_flag AtomicIncrement(volatile cas_flag* ptr); + cas_flag AtomicDecrement(volatile cas_flag* ptr); + cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val); + cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val); + cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val); } } diff --git a/include/llvm/System/ThreadLocal.h b/include/llvm/System/ThreadLocal.h new file mode 100644 index 0000000..39b1e64 --- /dev/null +++ b/include/llvm/System/ThreadLocal.h @@ -0,0 +1,41 @@ +//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the llvm::sys::ThreadLocal class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_THREAD_LOCAL_H +#define LLVM_SYSTEM_THREAD_LOCAL_H + +#include "llvm/System/Threading.h" +#include <cassert> + +namespace llvm { + namespace sys { + class ThreadLocalImpl { + void* data; + public: + ThreadLocalImpl(); + virtual ~ThreadLocalImpl(); + void setInstance(const void* d); + const void* getInstance(); + }; + + template<class T> + class ThreadLocal : public ThreadLocalImpl { + public: + ThreadLocal() : ThreadLocalImpl() { } + T* get() { return static_cast<T*>(getInstance()); } + void set(T* d) { setInstance(d); } + }; + } +} + +#endif diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 40b0e7b..02451c2 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -173,14 +173,18 @@ public: /// ValueTypeActions - This is a bitvector that contains two bits for each /// value type, where the two bits correspond to the LegalizeAction enum. /// This can be queried with "getTypeAction(VT)". - uint32_t ValueTypeActions[2]; + /// dimension by (MVT::MAX_ALLOWED_VALUETYPE/32) * 2 + uint32_t ValueTypeActions[(MVT::MAX_ALLOWED_VALUETYPE/32)*2]; public: ValueTypeActionImpl() { ValueTypeActions[0] = ValueTypeActions[1] = 0; + ValueTypeActions[2] = ValueTypeActions[3] = 0; } ValueTypeActionImpl(const ValueTypeActionImpl &RHS) { ValueTypeActions[0] = RHS.ValueTypeActions[0]; ValueTypeActions[1] = RHS.ValueTypeActions[1]; + ValueTypeActions[2] = RHS.ValueTypeActions[2]; + ValueTypeActions[3] = RHS.ValueTypeActions[3]; } LegalizeAction getTypeAction(MVT VT) const { @@ -349,10 +353,13 @@ public: /// for it. LegalizeAction getOperationAction(unsigned Op, MVT VT) const { if (VT.isExtended()) return Expand; - assert(Op < array_lengthof(OpActions) && - (unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*8 && + assert(Op < array_lengthof(OpActions[0]) && + (unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 && "Table isn't big enough!"); - return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3); + unsigned I = (unsigned) VT.getSimpleVT(); + unsigned J = I & 31; + I = I >> 5; + return (LegalizeAction)((OpActions[I][Op] >> (J*2) ) & 3); } /// isOperationLegalOrCustom - Return true if the specified operation is @@ -940,10 +947,13 @@ protected: /// with the specified type and indicate what to do about it. void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action) { - assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0])*8 && - Op < array_lengthof(OpActions) && "Table isn't big enough!"); - OpActions[Op] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2); - OpActions[Op] |= (uint64_t)Action << VT.getSimpleVT()*2; + assert((unsigned)VT.getSimpleVT() < sizeof(OpActions[0][0])*8 && + Op < array_lengthof(OpActions[0]) && "Table isn't big enough!"); + unsigned I = (unsigned) VT.getSimpleVT(); + unsigned J = I & 31; + I = I >> 5; + OpActions[I][Op] &= ~(uint64_t(3UL) << (J*2)); + OpActions[I][Op] |= (uint64_t)Action << (J*2); } /// setLoadExtAction - Indicate that the specified load with extension does @@ -1566,7 +1576,9 @@ private: /// Most operations are Legal (aka, supported natively by the target), but /// operations that are not should be described. Note that operations on /// non-legal value types are not described here. - uint64_t OpActions[ISD::BUILTIN_OP_END]; + /// This array is accessed using VT.getSimpleVT(), so it is subject to + /// the MVT::MAX_ALLOWED_VALUETYPE * 2 bits. + uint64_t OpActions[MVT::MAX_ALLOWED_VALUETYPE/(sizeof(uint64_t)*4)][ISD::BUILTIN_OP_END]; /// LoadExtActions - For each load of load extension type and each value type, /// keep a LegalizeAction that indicates how instruction selection should deal diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h index 8aa314a..002d5fc 100644 --- a/include/llvm/Target/TargetSelect.h +++ b/include/llvm/Target/TargetSelect.h @@ -18,20 +18,21 @@ #include "llvm/Config/config.h" -namespace llvm { +extern "C" { // Declare all of the target-initialization functions that are available. -#define LLVM_TARGET(TargetName) void Initialize##TargetName##Target(); +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" // Declare all of the available asm-printer initialization functions. - // Declare all of the target-initialization functions. -#define LLVM_ASM_PRINTER(TargetName) void Initialize##TargetName##AsmPrinter(); +#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" - +} + +namespace llvm { /// InitializeAllTargets - The main program should call this function if it /// wants to link in all available targets that LLVM is configured to support. inline void InitializeAllTargets() { -#define LLVM_TARGET(TargetName) llvm::Initialize##TargetName##Target(); +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" } @@ -39,18 +40,17 @@ namespace llvm { /// it wants all asm printers that LLVM is configured to support. This will /// cause them to be linked into its executable. inline void InitializeAllAsmPrinters() { -#define LLVM_ASM_PRINTER(TargetName) Initialize##TargetName##AsmPrinter(); +#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" } - /// InitializeNativeTarget - The main program should call this function to /// initialize the native target corresponding to the host. This is useful /// for JIT applications to ensure that the target gets linked in correctly. inline bool InitializeNativeTarget() { // If we have a native target, initialize it to ensure it is linked in. #ifdef LLVM_NATIVE_ARCH -#define DoInit2(TARG) llvm::Initialize ## TARG () +#define DoInit2(TARG) LLVMInitialize ## TARG () #define DoInit(T) DoInit2(T) DoInit(LLVM_NATIVE_ARCH); return false; diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 7ab8721..98a68f6 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -114,13 +114,6 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0); bool OnlyUsedByDbgInfoIntrinsics(Instruction *I, SmallVectorImpl<DbgInfoIntrinsic *> *DbgInUses = 0); -/// UserIsDebugInfo - Return true if U is a constant expr used by -/// llvm.dbg.variable or llvm.dbg.global_variable -bool UserIsDebugInfo(User *U); - -/// RemoveDbgInfoUser - Remove an User which is representing debug info. -void RemoveDbgInfoUser(User *U); - } // End llvm namespace #endif diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 97d5043..d439233 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -103,7 +103,7 @@ private: /// has no AbstractTypeUsers, the type is deleted. This is only sensical for /// derived types. /// - mutable int32_t RefCount; + mutable sys::cas_flag RefCount; const Type *getForwardedTypeInternal() const; @@ -338,7 +338,7 @@ public: void addRef() const { assert(isAbstract() && "Cannot add a reference to a non-abstract type!"); - sys::AtomicIncrement32(&RefCount); + sys::AtomicIncrement(&RefCount); } void dropRef() const { @@ -347,8 +347,8 @@ public: // If this is the last PATypeHolder using this object, and there are no // PATypeHandles using it, the type is dead, delete it now. - int32_t Count = sys::AtomicDecrement32(&RefCount); - if (Count == 0 && AbstractTypeUsers.empty()) + sys::cas_flag OldCount = sys::AtomicDecrement(&RefCount); + if (OldCount == 0 && AbstractTypeUsers.empty()) this->destroy(); } |