diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | 59850d0874429601812bc13408cb1f776649027c (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/VMCore | |
parent | 18f153bdb9db52e7089a2d5293b96c45a3124a26 (diff) |
Update llvm to r84119.vendor/llvm/llvm-r84119
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=198090
svn path=/vendor/llvm/llvm-84119/; revision=198091; tag=vendor/llvm/llvm-r84119
Diffstat (limited to 'lib/VMCore')
34 files changed, 6751 insertions, 4853 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index cbf7070d17ed..b5ae81b50f97 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -23,7 +23,8 @@ #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" -#include "llvm/MDNode.h" +#include "llvm/Operator.h" +#include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/TypeSymbolTable.h" @@ -31,8 +32,10 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" #include <algorithm> #include <cctype> #include <map> @@ -48,15 +51,15 @@ AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} static const Module *getModuleFromVal(const Value *V) { if (const Argument *MA = dyn_cast<Argument>(V)) return MA->getParent() ? MA->getParent()->getParent() : 0; - + if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) return BB->getParent() ? BB->getParent()->getParent() : 0; - + if (const Instruction *I = dyn_cast<Instruction>(V)) { const Function *M = I->getParent() ? I->getParent()->getParent() : 0; return M ? M->getParent() : 0; } - + if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV->getParent(); return 0; @@ -64,10 +67,10 @@ static const Module *getModuleFromVal(const Value *V) { // PrintEscapedString - Print each character of the specified string, escaping // it if it is not printable or if it is an escape char. -static void PrintEscapedString(const char *Str, unsigned Length, +static void PrintEscapedString(const StringRef &Name, raw_ostream &Out) { - for (unsigned i = 0; i != Length; ++i) { - unsigned char C = Str[i]; + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + unsigned char C = Name[i]; if (isprint(C) && C != '\\' && C != '"') Out << C; else @@ -75,12 +78,6 @@ static void PrintEscapedString(const char *Str, unsigned Length, } } -// PrintEscapedString - Print each character of the specified string, escaping -// it if it is not printable or if it is an escape char. -static void PrintEscapedString(const std::string &Str, raw_ostream &Out) { - PrintEscapedString(Str.c_str(), Str.size(), Out); -} - enum PrefixType { GlobalPrefix, LabelPrefix, @@ -91,39 +88,39 @@ enum PrefixType { /// PrintLLVMName - Turn the specified name into an 'LLVM name', which is either /// prefixed with % (if the string only contains simple characters) or is /// surrounded with ""'s (if it has special chars in it). Print it out. -static void PrintLLVMName(raw_ostream &OS, const char *NameStr, - unsigned NameLen, PrefixType Prefix) { - assert(NameStr && "Cannot get empty name!"); +static void PrintLLVMName(raw_ostream &OS, const StringRef &Name, + PrefixType Prefix) { + assert(Name.data() && "Cannot get empty name!"); switch (Prefix) { - default: assert(0 && "Bad prefix!"); + default: llvm_unreachable("Bad prefix!"); case NoPrefix: break; case GlobalPrefix: OS << '@'; break; case LabelPrefix: break; case LocalPrefix: OS << '%'; break; } - + // Scan the name to see if it needs quotes first. - bool NeedsQuotes = isdigit(NameStr[0]); + bool NeedsQuotes = isdigit(Name[0]); if (!NeedsQuotes) { - for (unsigned i = 0; i != NameLen; ++i) { - char C = NameStr[i]; + for (unsigned i = 0, e = Name.size(); i != e; ++i) { + char C = Name[i]; if (!isalnum(C) && C != '-' && C != '.' && C != '_') { NeedsQuotes = true; break; } } } - + // If we didn't need any quotes, just write out the name in one blast. if (!NeedsQuotes) { - OS.write(NameStr, NameLen); + OS << Name; return; } - + // Okay, we need quotes. Output the quotes and escape any scary characters as // needed. OS << '"'; - PrintEscapedString(NameStr, NameLen, OS); + PrintEscapedString(Name, OS); OS << '"'; } @@ -131,7 +128,7 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr, /// prefixed with % (if the string only contains simple characters) or is /// surrounded with ""'s (if it has special chars in it). Print it out. static void PrintLLVMName(raw_ostream &OS, const Value *V) { - PrintLLVMName(OS, V->getNameStart(), V->getNameLen(), + PrintLLVMName(OS, V->getName(), isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix); } @@ -178,11 +175,11 @@ void TypePrinting::CalcTypeName(const Type *Ty, return; } } - + // Check to see if the Type is already on the stack... unsigned Slot = 0, CurSize = TypeStack.size(); while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type - + // This is another base case for the recursion. In this case, we know // that we have looped back to a type that we have previously visited. // Generate the appropriate upreference to handle this. @@ -190,9 +187,9 @@ void TypePrinting::CalcTypeName(const Type *Ty, OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference return; } - + TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. - + switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; case Type::FloatTyID: OS << "float"; break; @@ -205,7 +202,7 @@ void TypePrinting::CalcTypeName(const Type *Ty, case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); break; - + case Type::FunctionTyID: { const FunctionType *FTy = cast<FunctionType>(Ty); CalcTypeName(FTy->getReturnType(), TypeStack, OS); @@ -269,7 +266,7 @@ void TypePrinting::CalcTypeName(const Type *Ty, OS << "<unrecognized-type>"; break; } - + TypeStack.pop_back(); // Remove self from stack. } @@ -287,13 +284,13 @@ void TypePrinting::print(const Type *Ty, raw_ostream &OS, return; } } - + // Otherwise we have a type that has not been named but is a derived type. // Carefully recurse the type hierarchy to print out any contained symbolic // names. SmallVector<const Type *, 16> TypeStack; std::string TypeName; - + raw_string_ostream TypeOS(TypeName); CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName); OS << TypeOS.str(); @@ -309,13 +306,13 @@ namespace { // objects, we keep several helper maps. DenseSet<const Value*> VisitedConstants; DenseSet<const Type*> VisitedTypes; - + TypePrinting &TP; std::vector<const Type*> &NumberedTypes; public: TypeFinder(TypePrinting &tp, std::vector<const Type*> &numberedTypes) : TP(tp), NumberedTypes(numberedTypes) {} - + void Run(const Module &M) { // Get types from the type symbol table. This gets opaque types referened // only through derived named types. @@ -323,7 +320,7 @@ namespace { for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); TI != E; ++TI) IncorporateType(TI->second); - + // Get types from global variables. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { @@ -331,18 +328,18 @@ namespace { if (I->hasInitializer()) IncorporateValue(I->getInitializer()); } - + // Get types from aliases. for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { IncorporateType(I->getType()); IncorporateValue(I->getAliasee()); } - + // Get types from functions. for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { IncorporateType(FI->getType()); - + for (Function::const_iterator BB = FI->begin(), E = FI->end(); BB != E;++BB) for (BasicBlock::const_iterator II = BB->begin(), @@ -356,40 +353,40 @@ namespace { } } } - + private: void IncorporateType(const Type *Ty) { // Check to see if we're already visited this type. if (!VisitedTypes.insert(Ty).second) return; - + // If this is a structure or opaque type, add a name for the type. if (((isa<StructType>(Ty) && cast<StructType>(Ty)->getNumElements()) || isa<OpaqueType>(Ty)) && !TP.hasTypeName(Ty)) { TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size()))); NumberedTypes.push_back(Ty); } - + // Recursively walk all contained types. for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); I != E; ++I) - IncorporateType(*I); + IncorporateType(*I); } - + /// IncorporateValue - This method is used to walk operand lists finding /// types hiding in constant expressions and other operands that won't be /// walked in other ways. GlobalValues, basic blocks, instructions, and /// inst operands are all explicitly enumerated. void IncorporateValue(const Value *V) { if (V == 0 || !isa<Constant>(V) || isa<GlobalValue>(V)) return; - + // Already visited? if (!VisitedConstants.insert(V).second) return; - + // Check this type. IncorporateType(V->getType()); - + // Look in operands for types. const Constant *C = cast<Constant>(V); for (Constant::const_op_iterator I = C->op_begin(), @@ -403,18 +400,18 @@ namespace { /// AddModuleTypesToPrinter - Add all of the symbolic type names for types in /// the specified module to the TypePrinter and all numbered types to it and the /// NumberedTypes table. -static void AddModuleTypesToPrinter(TypePrinting &TP, +static void AddModuleTypesToPrinter(TypePrinting &TP, std::vector<const Type*> &NumberedTypes, const Module *M) { if (M == 0) return; - + // If the module has a symbol table, take all global types and stuff their // names into the TypeNames map. const TypeSymbolTable &ST = M->getTypeSymbolTable(); for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end(); TI != E; ++TI) { const Type *Ty = cast<Type>(TI->second); - + // As a heuristic, don't insert pointer to primitive types, because // they are used too often to have a single useful name. if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { @@ -423,18 +420,20 @@ static void AddModuleTypesToPrinter(TypePrinting &TP, !isa<OpaqueType>(PETy)) continue; } - + // Likewise don't insert primitives either. if (Ty->isInteger() || Ty->isPrimitiveType()) continue; - + // Get the name as a string and insert it into TypeNames. std::string NameStr; - raw_string_ostream NameOS(NameStr); - PrintLLVMName(NameOS, TI->first.c_str(), TI->first.length(), LocalPrefix); - TP.addTypeName(Ty, NameOS.str()); + raw_string_ostream NameROS(NameStr); + formatted_raw_ostream NameOS(NameROS); + PrintLLVMName(NameOS, TI->first, LocalPrefix); + NameOS.flush(); + TP.addTypeName(Ty, NameStr); } - + // Walk the entire module to find references to unnamed structure and opaque // types. This is required for correctness by opaque types (because multiple // uses of an unnamed opaque type needs to be referred to by the same ID) and @@ -464,35 +463,49 @@ namespace { /// class SlotTracker { public: - /// ValueMap - A mapping of Values to slot numbers + /// ValueMap - A mapping of Values to slot numbers. typedef DenseMap<const Value*, unsigned> ValueMap; - -private: - /// TheModule - The module for which we are holding slot numbers + +private: + /// TheModule - The module for which we are holding slot numbers. const Module* TheModule; - - /// TheFunction - The function for which we are holding slot numbers + + /// TheFunction - The function for which we are holding slot numbers. const Function* TheFunction; bool FunctionProcessed; - - /// mMap - The TypePlanes map for the module level data + + /// TheMDNode - The MDNode for which we are holding slot numbers. + const MDNode *TheMDNode; + + /// TheNamedMDNode - The MDNode for which we are holding slot numbers. + const NamedMDNode *TheNamedMDNode; + + /// mMap - The TypePlanes map for the module level data. ValueMap mMap; unsigned mNext; - - /// fMap - The TypePlanes map for the function level data + + /// fMap - The TypePlanes map for the function level data. ValueMap fMap; unsigned fNext; - + + /// mdnMap - Map for MDNodes. + ValueMap mdnMap; + unsigned mdnNext; public: /// Construct from a module explicit SlotTracker(const Module *M); /// Construct from a function, starting out in incorp state. explicit SlotTracker(const Function *F); + /// Construct from a mdnode. + explicit SlotTracker(const MDNode *N); + /// Construct from a named mdnode. + explicit SlotTracker(const NamedMDNode *N); /// Return the slot number of the specified value in it's type /// plane. If something is not in the SlotTracker, return -1. int getLocalSlot(const Value *V); int getGlobalSlot(const GlobalValue *V); + int getMetadataSlot(const MDNode *N); /// If you'd like to deal with a function instead of just a module, use /// this method to get its data into the SlotTracker. @@ -506,14 +519,23 @@ public: /// will reset the state of the machine back to just the module contents. void purgeFunction(); - // Implementation Details -private: + /// MDNode map iterators. + ValueMap::iterator mdnBegin() { return mdnMap.begin(); } + ValueMap::iterator mdnEnd() { return mdnMap.end(); } + unsigned mdnSize() const { return mdnMap.size(); } + bool mdnEmpty() const { return mdnMap.empty(); } + /// This function does the actual initialization. inline void initialize(); + // Implementation Details +private: /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void CreateModuleSlot(const GlobalValue *V); - + + /// CreateMetadataSlot - Insert the specified MDNode* into the slot table. + void CreateMetadataSlot(const MDNode *N); + /// CreateFunctionSlot - Insert the specified Value* into the slot table. void CreateFunctionSlot(const Value *V); @@ -521,9 +543,15 @@ private: /// and function declarations, but not the contents of those functions. void processModule(); - /// Add all of the functions arguments, basic blocks, and instructions + /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); + /// Add all MDNode operands. + void processMDNode(); + + /// Add all MDNode operands. + void processNamedMDNode(); + SlotTracker(const SlotTracker &); // DO NOT IMPLEMENT void operator=(const SlotTracker &); // DO NOT IMPLEMENT }; @@ -534,27 +562,27 @@ private: static SlotTracker *createSlotTracker(const Value *V) { if (const Argument *FA = dyn_cast<Argument>(V)) return new SlotTracker(FA->getParent()); - + if (const Instruction *I = dyn_cast<Instruction>(V)) return new SlotTracker(I->getParent()->getParent()); - + if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) return new SlotTracker(BB->getParent()); - + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) return new SlotTracker(GV->getParent()); - + if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) - return new SlotTracker(GA->getParent()); - + return new SlotTracker(GA->getParent()); + if (const Function *Func = dyn_cast<Function>(V)) return new SlotTracker(Func); - + return 0; } #if 0 -#define ST_DEBUG(X) cerr << X +#define ST_DEBUG(X) errs() << X #else #define ST_DEBUG(X) #endif @@ -562,14 +590,27 @@ static SlotTracker *createSlotTracker(const Value *V) { // Module level constructor. Causes the contents of the Module (sans functions) // to be added to the slot table. SlotTracker::SlotTracker(const Module *M) - : TheModule(M), TheFunction(0), FunctionProcessed(false), mNext(0), fNext(0) { + : TheModule(M), TheFunction(0), FunctionProcessed(false), TheMDNode(0), + TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { } // Function level constructor. Causes the contents of the Module and the one // function provided to be added to the slot table. SlotTracker::SlotTracker(const Function *F) : TheModule(F ? F->getParent() : 0), TheFunction(F), FunctionProcessed(false), - mNext(0), fNext(0) { + TheMDNode(0), TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { +} + +// Constructor to handle single MDNode. +SlotTracker::SlotTracker(const MDNode *C) + : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(C), + TheNamedMDNode(0), mNext(0), fNext(0), mdnNext(0) { +} + +// Constructor to handle single NamedMDNode. +SlotTracker::SlotTracker(const NamedMDNode *N) + : TheModule(0), TheFunction(0), FunctionProcessed(false), TheMDNode(0), + TheNamedMDNode(N), mNext(0), fNext(0), mdnNext(0) { } inline void SlotTracker::initialize() { @@ -577,60 +618,120 @@ inline void SlotTracker::initialize() { processModule(); TheModule = 0; ///< Prevent re-processing next time we're called. } - + if (TheFunction && !FunctionProcessed) processFunction(); + + if (TheMDNode) + processMDNode(); + + if (TheNamedMDNode) + processNamedMDNode(); } // Iterate through all the global variables, functions, and global // variable initializers and create slots for them. void SlotTracker::processModule() { ST_DEBUG("begin processModule!\n"); - + // Add all of the unnamed global variables to the value table. for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) - if (!I->hasName()) + E = TheModule->global_end(); I != E; ++I) { + if (!I->hasName()) CreateModuleSlot(I); - + if (I->hasInitializer()) { + if (MDNode *N = dyn_cast<MDNode>(I->getInitializer())) + CreateMetadataSlot(N); + } + } + + // Add metadata used by named metadata. + for (Module::const_named_metadata_iterator + I = TheModule->named_metadata_begin(), + E = TheModule->named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { + MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i)); + if (MD) + CreateMetadataSlot(MD); + } + } + // Add all the unnamed functions to the table. for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); I != E; ++I) if (!I->hasName()) CreateModuleSlot(I); - + ST_DEBUG("end processModule!\n"); } - // Process the arguments, basic blocks, and instructions of a function. void SlotTracker::processFunction() { ST_DEBUG("begin processFunction!\n"); fNext = 0; - + // Add all the function arguments with no names. for(Function::const_arg_iterator AI = TheFunction->arg_begin(), AE = TheFunction->arg_end(); AI != AE; ++AI) if (!AI->hasName()) CreateFunctionSlot(AI); - + ST_DEBUG("Inserting Instructions:\n"); - + + MetadataContext &TheMetadata = TheFunction->getContext().getMetadata(); + // Add all of the basic blocks and instructions with no names. for (Function::const_iterator BB = TheFunction->begin(), E = TheFunction->end(); BB != E; ++BB) { if (!BB->hasName()) CreateFunctionSlot(BB); - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (I->getType() != Type::VoidTy && !I->hasName()) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; + ++I) { + if (I->getType() != Type::getVoidTy(TheFunction->getContext()) && + !I->hasName()) CreateFunctionSlot(I); + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (MDNode *N = dyn_cast_or_null<MDNode>(I->getOperand(i))) + CreateMetadataSlot(N); + + // Process metadata attached with this instruction. + const MetadataContext::MDMapTy *MDs = TheMetadata.getMDs(I); + if (MDs) + for (MetadataContext::MDMapTy::const_iterator MI = MDs->begin(), + ME = MDs->end(); MI != ME; ++MI) + if (MDNode *MDN = dyn_cast_or_null<MDNode>(MI->second)) + CreateMetadataSlot(MDN); + } } - + FunctionProcessed = true; - + ST_DEBUG("end processFunction!\n"); } +/// processMDNode - Process TheMDNode. +void SlotTracker::processMDNode() { + ST_DEBUG("begin processMDNode!\n"); + mdnNext = 0; + CreateMetadataSlot(TheMDNode); + TheMDNode = 0; + ST_DEBUG("end processMDNode!\n"); +} + +/// processNamedMDNode - Process TheNamedMDNode. +void SlotTracker::processNamedMDNode() { + ST_DEBUG("begin processNamedMDNode!\n"); + mdnNext = 0; + for (unsigned i = 0, e = TheNamedMDNode->getNumElements(); i != e; ++i) { + MDNode *MD = dyn_cast_or_null<MDNode>(TheNamedMDNode->getElement(i)); + if (MD) + CreateMetadataSlot(MD); + } + TheNamedMDNode = 0; + ST_DEBUG("end processNamedMDNode!\n"); +} + /// Clean up after incorporating a function. This is the only way to get out of /// the function incorporation state that affects get*Slot/Create*Slot. Function /// incorporation state is indicated by TheFunction != 0. @@ -646,20 +747,30 @@ void SlotTracker::purgeFunction() { int SlotTracker::getGlobalSlot(const GlobalValue *V) { // Check for uninitialized state and do lazy initialization. initialize(); - + // Find the type plane in the module map ValueMap::iterator MI = mMap.find(V); return MI == mMap.end() ? -1 : (int)MI->second; } +/// getGlobalSlot - Get the slot number of a MDNode. +int SlotTracker::getMetadataSlot(const MDNode *N) { + // Check for uninitialized state and do lazy initialization. + initialize(); + + // Find the type plane in the module map + ValueMap::iterator MI = mdnMap.find(N); + return MI == mdnMap.end() ? -1 : (int)MI->second; +} + /// getLocalSlot - Get the slot number for a value that is local to a function. int SlotTracker::getLocalSlot(const Value *V) { assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!"); - + // Check for uninitialized state and do lazy initialization. initialize(); - + ValueMap::iterator FI = fMap.find(V); return FI == fMap.end() ? -1 : (int)FI->second; } @@ -668,12 +779,13 @@ int SlotTracker::getLocalSlot(const Value *V) { /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void SlotTracker::CreateModuleSlot(const GlobalValue *V) { assert(V && "Can't insert a null Value into SlotTracker!"); - assert(V->getType() != Type::VoidTy && "Doesn't need a slot!"); + assert(V->getType() != Type::getVoidTy(V->getContext()) && + "Doesn't need a slot!"); assert(!V->hasName() && "Doesn't need a slot!"); - + unsigned DestSlot = mNext++; mMap[V] = DestSlot; - + ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" << DestSlot << " ["); // G = Global, F = Function, A = Alias, o = other @@ -682,28 +794,45 @@ void SlotTracker::CreateModuleSlot(const GlobalValue *V) { (isa<GlobalAlias>(V) ? 'A' : 'o'))) << "]\n"); } - /// CreateSlot - Create a new slot for the specified value if it has no name. void SlotTracker::CreateFunctionSlot(const Value *V) { - assert(V->getType() != Type::VoidTy && !V->hasName() && - "Doesn't need a slot!"); - + assert(V->getType() != Type::getVoidTy(TheFunction->getContext()) && + !V->hasName() && "Doesn't need a slot!"); + unsigned DestSlot = fNext++; fMap[V] = DestSlot; - + // G = Global, F = Function, o = other ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" << DestSlot << " [o]\n"); -} +} +/// CreateModuleSlot - Insert the specified MDNode* into the slot table. +void SlotTracker::CreateMetadataSlot(const MDNode *N) { + assert(N && "Can't insert a null Value into SlotTracker!"); + + ValueMap::iterator I = mdnMap.find(N); + if (I != mdnMap.end()) + return; + unsigned DestSlot = mdnNext++; + mdnMap[N] = DestSlot; + + for (MDNode::const_elem_iterator MDI = N->elem_begin(), + MDE = N->elem_end(); MDI != MDE; ++MDI) { + const Value *TV = *MDI; + if (TV) + if (const MDNode *N2 = dyn_cast<MDNode>(TV)) + CreateMetadataSlot(N2); + } +} //===----------------------------------------------------------------------===// // AsmWriter Implementation //===----------------------------------------------------------------------===// static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, - TypePrinting &TypePrinter, + TypePrinting *TypePrinter, SlotTracker *Machine); @@ -741,17 +870,93 @@ static const char *getPredicateText(unsigned predicate) { return pred; } +static void WriteMDNodeComment(const MDNode *Node, + formatted_raw_ostream &Out) { + if (Node->getNumElements() < 1) + return; + ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Node->getElement(0)); + if (!CI) return; + unsigned Val = CI->getZExtValue(); + unsigned Tag = Val & ~LLVMDebugVersionMask; + if (Val >= LLVMDebugVersion) { + if (Tag == dwarf::DW_TAG_auto_variable) + Out << "; [ DW_TAG_auto_variable ]"; + else if (Tag == dwarf::DW_TAG_arg_variable) + Out << "; [ DW_TAG_arg_variable ]"; + else if (Tag == dwarf::DW_TAG_return_variable) + Out << "; [ DW_TAG_return_variable ]"; + else if (Tag == dwarf::DW_TAG_vector_type) + Out << "; [ DW_TAG_vector_type ]"; + else if (Tag == dwarf::DW_TAG_user_base) + Out << "; [ DW_TAG_user_base ]"; + else + Out << "; [" << dwarf::TagString(Tag) << " ]"; + } +} + +static void WriteMDNodes(formatted_raw_ostream &Out, TypePrinting &TypePrinter, + SlotTracker &Machine) { + SmallVector<const MDNode *, 16> Nodes; + Nodes.resize(Machine.mdnSize()); + for (SlotTracker::ValueMap::iterator I = + Machine.mdnBegin(), E = Machine.mdnEnd(); I != E; ++I) + Nodes[I->second] = cast<MDNode>(I->first); + + for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { + Out << '!' << i << " = metadata "; + const MDNode *Node = Nodes[i]; + Out << "!{"; + for (MDNode::const_elem_iterator NI = Node->elem_begin(), + NE = Node->elem_end(); NI != NE;) { + const Value *V = *NI; + if (!V) + Out << "null"; + else if (const MDNode *N = dyn_cast<MDNode>(V)) { + Out << "metadata "; + Out << '!' << Machine.getMetadataSlot(N); + } + else { + TypePrinter.print((*NI)->getType(), Out); + Out << ' '; + WriteAsOperandInternal(Out, *NI, &TypePrinter, &Machine); + } + if (++NI != NE) + Out << ", "; + } + + Out << "}"; + WriteMDNodeComment(Node, Out); + Out << "\n"; + } +} + +static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { + if (const OverflowingBinaryOperator *OBO = + dyn_cast<OverflowingBinaryOperator>(U)) { + if (OBO->hasNoUnsignedWrap()) + Out << " nuw"; + if (OBO->hasNoSignedWrap()) + Out << " nsw"; + } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) { + if (Div->isExact()) + Out << " exact"; + } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { + if (GEP->isInBounds()) + Out << " inbounds"; + } +} + static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinting &TypePrinter, SlotTracker *Machine) { if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { - if (CI->getType() == Type::Int1Ty) { + if (CI->getType() == Type::getInt1Ty(CV->getContext())) { Out << (CI->getZExtValue() ? "true" : "false"); return; } Out << CI->getValue(); return; } - + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble || &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) { @@ -789,14 +994,14 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, APFloat apf = CFP->getValueAPF(); // Floats are represented in ASCII IR as double, convert. if (!isDouble) - apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, + apf.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored); - Out << "0x" << - utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), + Out << "0x" << + utohex_buffer(uint64_t(apf.bitcastToAPInt().getZExtValue()), Buffer+40); return; } - + // Some form of long double. These appear as a magic letter identifying // the type, then a fixed number of hex digits. Out << "0x"; @@ -827,7 +1032,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble) Out << 'M'; else - assert(0 && "Unsupported floating point type"); + llvm_unreachable("Unsupported floating point type"); // api needed to prevent premature destruction APInt api = CFP->getValueAPF().bitcastToAPInt(); const uint64_t* p = api.getRawData(); @@ -849,12 +1054,12 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, } return; } - + if (isa<ConstantAggregateZero>(CV)) { Out << "zeroinitializer"; return; } - + if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) { // As a special case, print the array as a string if it is an array of // i8 with ConstantInt values. @@ -870,19 +1075,19 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinter.print(ETy, Out); Out << ' '; WriteAsOperandInternal(Out, CA->getOperand(0), - TypePrinter, Machine); + &TypePrinter, Machine); for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CA->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine); } } Out << ']'; } return; } - + if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) { if (CS->getType()->isPacked()) Out << '<'; @@ -893,24 +1098,24 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, TypePrinter.print(CS->getOperand(0)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, CS->getOperand(0), TypePrinter, Machine); + WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine); for (unsigned i = 1; i < N; i++) { Out << ", "; TypePrinter.print(CS->getOperand(i)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, CS->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine); } Out << ' '; } - + Out << '}'; if (CS->getType()->isPacked()) Out << '>'; return; } - + if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { const Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && @@ -918,36 +1123,35 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << '<'; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(0), TypePrinter, Machine); + WriteAsOperandInternal(Out, CP->getOperand(0), &TypePrinter, Machine); for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; - WriteAsOperandInternal(Out, CP->getOperand(i), TypePrinter, Machine); + WriteAsOperandInternal(Out, CP->getOperand(i), &TypePrinter, Machine); } Out << '>'; return; } - + if (isa<ConstantPointerNull>(CV)) { Out << "null"; return; } - + if (isa<UndefValue>(CV)) { Out << "undef"; return; } - - if (const MDString *S = dyn_cast<MDString>(CV)) { - Out << "!\""; - PrintEscapedString(S->begin(), S->size(), Out); - Out << '"'; + + if (const MDNode *Node = dyn_cast<MDNode>(CV)) { + Out << "!" << Machine->getMetadataSlot(Node); return; } if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { Out << CE->getOpcodeName(); + WriteOptimizationInfo(Out, CE); if (CE->isCompare()) Out << ' ' << getPredicateText(CE->getPredicate()); Out << " ("; @@ -955,7 +1159,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) { TypePrinter.print((*OI)->getType(), Out); Out << ' '; - WriteAsOperandInternal(Out, *OI, TypePrinter, Machine); + WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine); if (OI+1 != CE->op_end()) Out << ", "; } @@ -974,7 +1178,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << ')'; return; } - + Out << "<placeholder or erroneous Constant>"; } @@ -984,23 +1188,26 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, /// the whole instruction that generated it. /// static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, - TypePrinting &TypePrinter, + TypePrinting *TypePrinter, SlotTracker *Machine) { if (V->hasName()) { PrintLLVMName(Out, V); return; } - + const Constant *CV = dyn_cast<Constant>(V); if (CV && !isa<GlobalValue>(CV)) { - WriteConstantInt(Out, CV, TypePrinter, Machine); + assert(TypePrinter && "Constants require TypePrinting!"); + WriteConstantInt(Out, CV, *TypePrinter, Machine); return; } - + if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { Out << "asm "; if (IA->hasSideEffects()) Out << "sideeffect "; + if (IA->isMsAsm()) + Out << "msasm "; Out << '"'; PrintEscapedString(IA->getAsmString(), Out); Out << "\", \""; @@ -1008,7 +1215,24 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, Out << '"'; return; } - + + if (const MDNode *N = dyn_cast<MDNode>(V)) { + Out << '!' << Machine->getMetadataSlot(N); + return; + } + + if (const MDString *MDS = dyn_cast<MDString>(V)) { + Out << "!\""; + PrintEscapedString(MDS->getString(), Out); + Out << '"'; + return; + } + + if (V->getValueID() == Value::PseudoSourceValueVal) { + V->print(Out); + return; + } + char Prefix = '%'; int Slot; if (Machine) { @@ -1027,30 +1251,29 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V, } else { Slot = Machine->getLocalSlot(V); } + delete Machine; } else { Slot = -1; } - delete Machine; } - + if (Slot != -1) Out << Prefix << Slot; else Out << "<badref>"; } -/// WriteAsOperand - Write the name of the specified value out to the specified -/// ostream. This can be useful when you just want to print int %reg126, not -/// the whole instruction that generated it. -/// -void llvm::WriteAsOperand(std::ostream &Out, const Value *V, bool PrintType, - const Module *Context) { - raw_os_ostream OS(Out); - WriteAsOperand(OS, V, PrintType, Context); -} +void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, + bool PrintType, const Module *Context) { + + // Fast path: Don't construct and populate a TypePrinting object if we + // won't be needing any types printed. + if (!PrintType && + (!isa<Constant>(V) || V->hasName() || isa<GlobalValue>(V))) { + WriteAsOperandInternal(Out, V, 0, 0); + return; + } -void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType, - const Module *Context) { if (Context == 0) Context = getModuleFromVal(V); TypePrinting TypePrinter; @@ -1061,32 +1284,40 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType, Out << ' '; } - WriteAsOperandInternal(Out, V, TypePrinter, 0); + WriteAsOperandInternal(Out, V, &TypePrinter, 0); } - namespace { class AssemblyWriter { - raw_ostream &Out; + formatted_raw_ostream &Out; SlotTracker &Machine; const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; std::vector<const Type*> NumberedTypes; + DenseMap<unsigned, const char *> MDNames; - // Each MDNode is assigned unique MetadataIDNo. - std::map<const MDNode *, unsigned> MDNodes; - unsigned MetadataIDNo; public: - inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M, + inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, + const Module *M, AssemblyAnnotationWriter *AAW) - : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) { + : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); + // FIXME: Provide MDPrinter + if (M) { + MetadataContext &TheMetadata = M->getContext().getMetadata(); + const StringMap<unsigned> *Names = TheMetadata.getHandlerNames(); + for (StringMapConstIterator<unsigned> I = Names->begin(), + E = Names->end(); I != E; ++I) { + const StringMapEntry<unsigned> &Entry = *I; + MDNames[I->second] = Entry.getKeyData(); + } + } } void write(const Module *M) { printModule(M); } - + void write(const GlobalValue *G) { if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) printGlobal(GV); @@ -1095,17 +1326,14 @@ public: else if (const Function *F = dyn_cast<Function>(G)) printFunction(F); else - assert(0 && "Unknown global"); + llvm_unreachable("Unknown global"); } - + void write(const BasicBlock *BB) { printBasicBlock(BB); } void write(const Instruction *I) { printInstruction(*I); } void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, Attributes Attrs); - void printMDNode(const MDNode *Node, bool StandAlone); - - const Module* getModule() { return TheModule; } private: void printModule(const Module *M); @@ -1132,11 +1360,11 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) { TypePrinter.print(Operand->getType(), Out); Out << ' '; } - WriteAsOperandInternal(Out, Operand, TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } } -void AssemblyWriter::writeParamOperand(const Value *Operand, +void AssemblyWriter::writeParamOperand(const Value *Operand, Attributes Attrs) { if (Operand == 0) { Out << "<null operand!>"; @@ -1148,7 +1376,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, Out << ' ' << Attribute::getAsString(Attrs); Out << ' '; // Print the operand - WriteAsOperandInternal(Out, Operand, TypePrinter, &Machine); + WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine); } } @@ -1169,6 +1397,7 @@ void AssemblyWriter::printModule(const Module *M) { std::string Asm = M->getModuleInlineAsm(); size_t CurPos = 0; size_t NewLine = Asm.find_first_of('\n', CurPos); + Out << '\n'; while (NewLine != std::string::npos) { // We found a newline, print the portion of the asm string from the // last newline up to this newline. @@ -1183,11 +1412,12 @@ void AssemblyWriter::printModule(const Module *M) { PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out); Out << "\"\n"; } - + // Loop over the dependent libraries and emit them. Module::lib_iterator LI = M->lib_begin(); Module::lib_iterator LE = M->lib_end(); if (LI != LE) { + Out << '\n'; Out << "deplibs = [ "; while (LI != LE) { Out << '"' << *LI << '"'; @@ -1195,16 +1425,19 @@ void AssemblyWriter::printModule(const Module *M) { if (LI != LE) Out << ", "; } - Out << " ]\n"; + Out << " ]"; } // Loop over the symbol table, emitting all id'd types. + if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n'; printTypeSymbolTable(M->getTypeSymbolTable()); + // Output all globals. + if (!M->global_empty()) Out << '\n'; for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) printGlobal(I); - + // Output all aliases. if (!M->alias_empty()) Out << "\n"; for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); @@ -1214,36 +1447,55 @@ void AssemblyWriter::printModule(const Module *M) { // Output all of the functions. for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) printFunction(I); + + // Output named metadata. + if (!M->named_metadata_empty()) Out << '\n'; + for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), + E = M->named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + Out << "!" << NMD->getName() << " = !{"; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) { + if (i) Out << ", "; + MDNode *MD = dyn_cast_or_null<MDNode>(NMD->getElement(i)); + Out << '!' << Machine.getMetadataSlot(MD); + } + Out << "}\n"; + } + + // Output metadata. + if (!Machine.mdnEmpty()) Out << '\n'; + WriteMDNodes(Out, TypePrinter, Machine); } -static void PrintLinkage(GlobalValue::LinkageTypes LT, raw_ostream &Out) { +static void PrintLinkage(GlobalValue::LinkageTypes LT, + formatted_raw_ostream &Out) { switch (LT) { - case GlobalValue::PrivateLinkage: Out << "private "; break; - case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::ExternalLinkage: break; + case GlobalValue::PrivateLinkage: Out << "private "; break; + case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break; + case GlobalValue::InternalLinkage: Out << "internal "; break; + case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; + case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; + case GlobalValue::WeakAnyLinkage: Out << "weak "; break; + case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; + case GlobalValue::CommonLinkage: Out << "common "; break; + case GlobalValue::AppendingLinkage: Out << "appending "; break; + case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; + case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; + case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; case GlobalValue::AvailableExternallyLinkage: Out << "available_externally "; break; - case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; - case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; - case GlobalValue::WeakAnyLinkage: Out << "weak "; break; - case GlobalValue::WeakODRLinkage: Out << "weak_odr "; break; - case GlobalValue::CommonLinkage: Out << "common "; break; - case GlobalValue::AppendingLinkage: Out << "appending "; break; - case GlobalValue::DLLImportLinkage: Out << "dllimport "; break; - case GlobalValue::DLLExportLinkage: Out << "dllexport "; break; - case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break; - case GlobalValue::ExternalLinkage: break; case GlobalValue::GhostLinkage: - Out << "GhostLinkage not allowed in AsmWriter!\n"; - abort(); + llvm_unreachable("GhostLinkage not allowed in AsmWriter!"); } } static void PrintVisibility(GlobalValue::VisibilityTypes Vis, - raw_ostream &Out) { + formatted_raw_ostream &Out) { switch (Vis) { - default: assert(0 && "Invalid visibility style!"); + default: llvm_unreachable("Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; case GlobalValue::ProtectedVisibility: Out << "protected "; break; @@ -1251,36 +1503,12 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, } void AssemblyWriter::printGlobal(const GlobalVariable *GV) { - if (GV->hasInitializer()) - // If GV is initialized using Metadata then separate out metadata - // operands used by the initializer. Note, MDNodes are not cyclic. - if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) { - SmallVector<const MDNode *, 4> WorkList; - // Collect MDNodes used by the initializer. - for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); - I != E; ++I) { - const Value *TV = *I; - if (TV) - if (const MDNode *NN = dyn_cast<MDNode>(TV)) - WorkList.push_back(NN); - } - - // Print MDNodes used by the initializer. - while (!WorkList.empty()) { - const MDNode *N = WorkList.back(); WorkList.pop_back(); - printMDNode(N, true); - Out << '\n'; - } - } - - if (GV->hasName()) { - PrintLLVMName(Out, GV); - Out << " = "; - } + WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine); + Out << " = "; if (!GV->hasInitializer() && GV->hasExternalLinkage()) Out << "external "; - + PrintLinkage(GV->getLinkage(), Out); PrintVisibility(GV->getVisibility(), Out); @@ -1292,12 +1520,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { if (GV->hasInitializer()) { Out << ' '; - if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) - printMDNode(N, false); - else - writeOperand(GV->getInitializer(), false); + writeOperand(GV->getInitializer(), false); } - + if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; if (GV->getAlignment()) @@ -1307,47 +1532,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { Out << '\n'; } -void AssemblyWriter::printMDNode(const MDNode *Node, - bool StandAlone) { - std::map<const MDNode *, unsigned>::iterator MI = MDNodes.find(Node); - // If this node is already printed then just refer it using its Metadata - // id number. - if (MI != MDNodes.end()) { - if (!StandAlone) - Out << "!" << MI->second; - return; - } - - if (StandAlone) { - // Print standalone MDNode. - // !42 = !{ ... } - Out << "!" << MetadataIDNo << " = "; - Out << "constant metadata "; - } - - Out << "!{"; - for (MDNode::const_elem_iterator I = Node->elem_begin(), E = Node->elem_end(); - I != E;) { - const Value *TV = *I; - if (!TV) - Out << "null"; - else if (const MDNode *N = dyn_cast<MDNode>(TV)) { - TypePrinter.print(N->getType(), Out); - Out << ' '; - printMDNode(N, StandAlone); - } - else if (!*I) - Out << "null"; - else - writeOperand(*I, true); - if (++I != E) - Out << ", "; - } - Out << "}"; - - MDNodes[Node] = MetadataIDNo++; -} - void AssemblyWriter::printAlias(const GlobalAlias *GA) { // Don't crash when dumping partially built GA if (!GA->hasName()) @@ -1361,9 +1545,9 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << "alias "; PrintLinkage(GA->getLinkage(), Out); - + const Constant *Aliasee = GA->getAliasee(); - + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { TypePrinter.print(GV->getType(), Out); Out << ' '; @@ -1372,7 +1556,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { TypePrinter.print(F->getFunctionType(), Out); Out << "* "; - WriteAsOperandInternal(Out, F, TypePrinter, &Machine); + WriteAsOperandInternal(Out, F, &TypePrinter, &Machine); } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) { TypePrinter.print(GA->getType(), Out); Out << ' '; @@ -1385,7 +1569,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { "Unsupported aliasee"); writeOperand(CE, false); } - + printInfoComment(*GA); Out << '\n'; } @@ -1393,19 +1577,18 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { // Emit all numbered types. for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) { - Out << "\ttype "; - + Out << '%' << i << " = type "; + // Make sure we print out at least one level of the type structure, so // that we do not get %2 = type %2 TypePrinter.printAtLeastOneLevel(NumberedTypes[i], Out); - Out << "\t\t; type %" << i << '\n'; + Out << '\n'; } - + // Print the named types. for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); TI != TE; ++TI) { - Out << '\t'; - PrintLLVMName(Out, &TI->first[0], TI->first.size(), LocalPrefix); + PrintLLVMName(Out, TI->first, LocalPrefix); Out << " = type "; // Make sure we print out at least one level of the type structure, so @@ -1427,7 +1610,7 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "declare "; else Out << "define "; - + PrintLinkage(F->getLinkage(), Out); PrintVisibility(F->getVisibility(), Out); @@ -1451,7 +1634,7 @@ void AssemblyWriter::printFunction(const Function *F) { Out << Attribute::getAsString(Attrs.getRetAttributes()) << ' '; TypePrinter.print(F->getReturnType(), Out); Out << ' '; - WriteAsOperandInternal(Out, F, TypePrinter, &Machine); + WriteAsOperandInternal(Out, F, &TypePrinter, &Machine); Out << '('; Machine.incorporateFunction(F); @@ -1472,10 +1655,10 @@ void AssemblyWriter::printFunction(const Function *F) { for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { // Insert commas as we go... the first arg doesn't get a comma if (i) Out << ", "; - + // Output type... TypePrinter.print(FT->getParamType(i), Out); - + Attributes ArgAttrs = Attrs.getParamAttributes(i+1); if (ArgAttrs != Attribute::None) Out << ' ' << Attribute::getAsString(ArgAttrs); @@ -1515,7 +1698,7 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out /// -void AssemblyWriter::printArgument(const Argument *Arg, +void AssemblyWriter::printArgument(const Argument *Arg, Attributes Attrs) { // Output type... TypePrinter.print(Arg->getType(), Out); @@ -1536,7 +1719,7 @@ void AssemblyWriter::printArgument(const Argument *Arg, void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... Out << "\n"; - PrintLLVMName(Out, BB->getNameStart(), BB->getNameLen(), LabelPrefix); + PrintLLVMName(Out, BB->getName(), LabelPrefix); Out << ':'; } else if (!BB->use_empty()) { // Don't print block # of no uses... Out << "\n; <label>:"; @@ -1547,13 +1730,15 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { Out << "<badref>"; } - if (BB->getParent() == 0) - Out << "\t\t; Error: Block without parent!"; - else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block? + if (BB->getParent() == 0) { + Out.PadToColumn(50); + Out << "; Error: Block without parent!"; + } else if (BB != &BB->getParent()->getEntryBlock()) { // Not the entry block? // Output predecessors for the block... - Out << "\t\t;"; + Out.PadToColumn(50); + Out << ";"; pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB); - + if (PI == PE) { Out << " No predecessors!"; } else { @@ -1571,8 +1756,10 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out); // Output all of the instructions in the basic block... - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { printInstruction(*I); + Out << '\n'; + } if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } @@ -1582,23 +1769,11 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { /// which slot it occupies. /// void AssemblyWriter::printInfoComment(const Value &V) { - if (V.getType() != Type::VoidTy) { - Out << "\t\t; <"; + if (V.getType() != Type::getVoidTy(V.getContext())) { + Out.PadToColumn(50); + Out << "; <"; TypePrinter.print(V.getType(), Out); - Out << '>'; - - if (!V.hasName() && !isa<Instruction>(V)) { - int SlotNum; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(&V)) - SlotNum = Machine.getGlobalSlot(GV); - else - SlotNum = Machine.getLocalSlot(&V); - if (SlotNum == -1) - Out << ":<badref>"; - else - Out << ':' << SlotNum; // Print out the def slot taken. - } - Out << " [#uses=" << V.getNumUses() << ']'; // Output # uses + Out << "> [#uses=" << V.getNumUses() << ']'; // Output # uses } } @@ -1606,13 +1781,14 @@ void AssemblyWriter::printInfoComment(const Value &V) { void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); - Out << '\t'; + // Print out indentation for an instruction. + Out << " "; // Print out name if it exists... if (I.hasName()) { PrintLLVMName(Out, &I); Out << " = "; - } else if (I.getType() != Type::VoidTy) { + } else if (I.getType() != Type::getVoidTy(I.getContext())) { // Print out the def slot taken. int SlotNum = Machine.getLocalSlot(&I); if (SlotNum == -1) @@ -1633,6 +1809,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Print out the opcode... Out << I.getOpcodeName(); + // Print out optimization information. + WriteOptimizationInfo(Out, &I); + // Print out the compare instruction predicates if (const CmpInst *CI = dyn_cast<CmpInst>(&I)) Out << ' ' << getPredicateText(CI->getPredicate()); @@ -1659,12 +1838,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " ["; for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) { - Out << "\n\t\t"; + Out << "\n "; writeOperand(I.getOperand(op ), true); Out << ", "; writeOperand(I.getOperand(op+1), true); } - Out << "\n\t]"; + Out << "\n ]"; } else if (isa<PHINode>(I)) { Out << ' '; TypePrinter.print(I.getType(), Out); @@ -1781,7 +1960,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.getFnAttributes() != Attribute::None) Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); - Out << "\n\t\t\tto "; + Out << "\n to "; writeOperand(II->getNormalDest(), true); Out << " unwind "; writeOperand(II->getUnwindDest(), true); @@ -1789,7 +1968,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) { Out << ' '; TypePrinter.print(AI->getType()->getElementType(), Out); - if (AI->isArrayAllocation()) { + if (!AI->getArraySize() || AI->isArrayAllocation()) { Out << ", "; writeOperand(AI->getArraySize(), true); } @@ -1845,7 +2024,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(i), PrintAllTypes); } } - + // Print post operand alignment for load/store if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) { Out << ", align " << cast<LoadInst>(I).getAlignment(); @@ -1853,8 +2032,18 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ", align " << cast<StoreInst>(I).getAlignment(); } + // Print Metadata info + if (!MDNames.empty()) { + MetadataContext &TheMetadata = I.getContext().getMetadata(); + const MetadataContext::MDMapTy *MDMap = TheMetadata.getMDs(&I); + if (MDMap) + for (MetadataContext::MDMapTy::const_iterator MI = MDMap->begin(), + ME = MDMap->end(); MI != ME; ++MI) + if (const MDNode *MD = dyn_cast_or_null<MDNode>(MI->second)) + Out << ", !" << MDNames[MI->first] + << " !" << Machine.getMetadataSlot(MD); + } printInfoComment(I); - Out << '\n'; } @@ -1862,21 +2051,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // External Interface declarations //===----------------------------------------------------------------------===// -void Module::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const { - raw_os_ostream OS(o); - print(OS, AAW); -} -void Module::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { +void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(this); + formatted_raw_ostream OS(ROS); AssemblyWriter W(OS, SlotTable, this, AAW); W.write(this); } -void Type::print(std::ostream &o) const { - raw_os_ostream OS(o); - print(OS); -} - void Type::print(raw_ostream &OS) const { if (this == 0) { OS << "<null Type>"; @@ -1885,12 +2066,12 @@ void Type::print(raw_ostream &OS) const { TypePrinting().print(this, OS); } -void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { +void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { if (this == 0) { - OS << "printing a <null> value\n"; + ROS << "printing a <null> value\n"; return; } - + formatted_raw_ostream OS(ROS); if (const Instruction *I = dyn_cast<Instruction>(this)) { const Function *F = I->getParent() ? I->getParent()->getParent() : 0; SlotTracker SlotTable(F); @@ -1905,14 +2086,33 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(GV->getParent()); AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW); W.write(GV); - } else if (const MDNode *N = dyn_cast<MDNode>(this)) { + } else if (const MDString *MDS = dyn_cast<MDString>(this)) { TypePrinting TypePrinter; - TypePrinter.print(N->getType(), OS); + TypePrinter.print(MDS->getType(), OS); OS << ' '; - // FIXME: Do we need a slot tracker for metadata ? - SlotTracker SlotTable((const Function *)NULL); - AssemblyWriter W(OS, SlotTable, NULL, AAW); - W.printMDNode(N, false); + OS << "!\""; + PrintEscapedString(MDS->getString(), OS); + OS << '"'; + } else if (const MDNode *N = dyn_cast<MDNode>(this)) { + SlotTracker SlotTable(N); + TypePrinting TypePrinter; + SlotTable.initialize(); + WriteMDNodes(OS, TypePrinter, SlotTable); + } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) { + SlotTracker SlotTable(N); + TypePrinting TypePrinter; + SlotTable.initialize(); + OS << "!" << N->getName() << " = !{"; + for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) { + if (i) OS << ", "; + MDNode *MD = dyn_cast_or_null<MDNode>(N->getElement(i)); + if (MD) + OS << '!' << SlotTable.getMetadataSlot(MD); + else + OS << "null"; + } + OS << "}\n"; + WriteMDNodes(OS, TypePrinter, SlotTable); } else if (const Constant *C = dyn_cast<Constant>(this)) { TypePrinting TypePrinter; TypePrinter.print(C->getType(), OS); @@ -1924,13 +2124,15 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const { } else if (isa<InlineAsm>(this)) { WriteAsOperand(OS, this, true, 0); } else { - assert(0 && "Unknown value to print out!"); + // Otherwise we don't know what it is. Call the virtual function to + // allow a subclass to print itself. + printCustom(OS); } } -void Value::print(std::ostream &O, AssemblyAnnotationWriter *AAW) const { - raw_os_ostream OS(O); - print(OS, AAW); +// Value::printCustom - subclasses should override this to implement printing. +void Value::printCustom(raw_ostream &OS) const { + llvm_unreachable("Unknown value to print out!"); } // Value::dump - allow easy printing of Values from the debugger. diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 8dfbd1d50216..d68bba30729d 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -15,8 +15,10 @@ #include "llvm/Type.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/Streams.h" +#include "llvm/System/Atomic.h" +#include "llvm/System/Mutex.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -40,7 +42,7 @@ std::string Attribute::getAsString(Attributes Attrs) { if (Attrs & Attribute::NoCapture) Result += "nocapture "; if (Attrs & Attribute::StructRet) - Result += "sret "; + Result += "sret "; if (Attrs & Attribute::ByVal) Result += "byval "; if (Attrs & Attribute::Nest) @@ -53,6 +55,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "optsize "; if (Attrs & Attribute::NoInline) Result += "noinline "; + if (Attrs & Attribute::InlineHint) + Result += "inlinehint "; if (Attrs & Attribute::AlwaysInline) Result += "alwaysinline "; if (Attrs & Attribute::StackProtect) @@ -63,6 +67,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "noredzone "; if (Attrs & Attribute::NoImplicitFloat) Result += "noimplicitfloat "; + if (Attrs & Attribute::Naked) + Result += "naked "; if (Attrs & Attribute::Alignment) { Result += "align "; Result += utostr(Attribute::getAlignmentFromAttrs(Attrs)); @@ -94,7 +100,7 @@ Attributes Attribute::typeIncompatible(const Type *Ty) { namespace llvm { class AttributeListImpl : public FoldingSetNode { - unsigned RefCount; + sys::cas_flag RefCount; // AttributesList is uniqued, these should not be publicly available. void operator=(const AttributeListImpl &); // Do not implement @@ -108,8 +114,11 @@ public: RefCount = 0; } - void AddRef() { ++RefCount; } - void DropRef() { if (--RefCount == 0) delete this; } + void AddRef() { sys::AtomicIncrement(&RefCount); } + void DropRef() { + sys::cas_flag old = sys::AtomicDecrement(&RefCount); + if (old == 0) delete this; + } void Profile(FoldingSetNodeID &ID) const { Profile(ID, Attrs.data(), Attrs.size()); @@ -122,9 +131,11 @@ public: }; } +static ManagedStatic<sys::SmartMutex<true> > ALMutex; static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists; AttributeListImpl::~AttributeListImpl() { + sys::SmartScopedLock<true> Lock(*ALMutex); AttributesLists->RemoveNode(this); } @@ -147,6 +158,9 @@ AttrListPtr AttrListPtr::get(const AttributeWithIndex *Attrs, unsigned NumAttrs) FoldingSetNodeID ID; AttributeListImpl::Profile(ID, Attrs, NumAttrs); void *InsertPos; + + sys::SmartScopedLock<true> Lock(*ALMutex); + AttributeListImpl *PAL = AttributesLists->FindNodeOrInsertPos(ID, InsertPos); @@ -304,11 +318,11 @@ AttrListPtr AttrListPtr::removeAttr(unsigned Idx, Attributes Attrs) const { } void AttrListPtr::dump() const { - cerr << "PAL[ "; + errs() << "PAL[ "; for (unsigned i = 0; i < getNumSlots(); ++i) { const AttributeWithIndex &PAWI = getSlot(i); - cerr << "{" << PAWI.Index << "," << PAWI.Attrs << "} "; + errs() << "{" << PAWI.Index << "," << PAWI.Attrs << "} "; } - cerr << "]\n"; + errs() << "]\n"; } diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index dd366071b76b..77ab19f417ce 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -14,10 +14,11 @@ #include "llvm/AutoUpgrade.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/LLVMContext.h" #include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ErrorHandling.h" #include <cstring> using namespace llvm; @@ -119,6 +120,31 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; + case 'e': + // The old llvm.eh.selector.i32 is equivalent to the new llvm.eh.selector. + if (Name.compare("llvm.eh.selector.i32") == 0) { + F->setName("llvm.eh.selector"); + NewFn = F; + return true; + } + // The old llvm.eh.typeid.for.i32 is equivalent to llvm.eh.typeid.for. + if (Name.compare("llvm.eh.typeid.for.i32") == 0) { + F->setName("llvm.eh.typeid.for"); + NewFn = F; + return true; + } + // Convert the old llvm.eh.selector.i64 to a call to llvm.eh.selector. + if (Name.compare("llvm.eh.selector.i64") == 0) { + NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_selector); + return true; + } + // Convert the old llvm.eh.typeid.for.i64 to a call to llvm.eh.typeid.for. + if (Name.compare("llvm.eh.typeid.for.i64") == 0) { + NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_typeid_for); + return true; + } + break; + case 'p': // This upgrades the llvm.part.select overloaded intrinsic names to only // use one type specifier in the name. We only care about the old format @@ -162,7 +188,8 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name.compare(13,4,"psra", 4) == 0 || Name.compare(13,4,"psrl", 4) == 0) && Name[17] != 'i') { - const llvm::Type *VT = VectorType::get(IntegerType::get(64), 1); + const llvm::Type *VT = + VectorType::get(IntegerType::get(FTy->getContext(), 64), 1); // We don't have to do anything if the parameter already has // the correct type. @@ -227,6 +254,8 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { // order to seamlessly integrate with existing context. void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Function *F = CI->getCalledFunction(); + LLVMContext &C = CI->getContext(); + assert(F && "CallInst has no function associated with it."); if (!NewFn) { @@ -234,23 +263,23 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { bool isMovSD = false, isShufPD = false; bool isUnpckhPD = false, isUnpcklPD = false; bool isPunpckhQPD = false, isPunpcklQPD = false; - if (strcmp(F->getNameStart(), "llvm.x86.sse2.loadh.pd") == 0) + if (F->getName() == "llvm.x86.sse2.loadh.pd") isLoadH = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.loadl.pd") == 0) + else if (F->getName() == "llvm.x86.sse2.loadl.pd") isLoadL = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.movl.dq") == 0) + else if (F->getName() == "llvm.x86.sse2.movl.dq") isMovL = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.movs.d") == 0) + else if (F->getName() == "llvm.x86.sse2.movs.d") isMovSD = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.shuf.pd") == 0) + else if (F->getName() == "llvm.x86.sse2.shuf.pd") isShufPD = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.unpckh.pd") == 0) + else if (F->getName() == "llvm.x86.sse2.unpckh.pd") isUnpckhPD = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.unpckl.pd") == 0) + else if (F->getName() == "llvm.x86.sse2.unpckl.pd") isUnpcklPD = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.punpckh.qdq") == 0) + else if (F->getName() == "llvm.x86.sse2.punpckh.qdq") isPunpckhQPD = true; - else if (strcmp(F->getNameStart(), "llvm.x86.sse2.punpckl.qdq") == 0) + else if (F->getName() == "llvm.x86.sse2.punpckl.qdq") isPunpcklQPD = true; if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD || @@ -261,23 +290,23 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { if (isLoadH || isLoadL) { Value *Op1 = UndefValue::get(Op0->getType()); Value *Addr = new BitCastInst(CI->getOperand(2), - PointerType::getUnqual(Type::DoubleTy), + Type::getDoublePtrTy(C), "upgraded.", CI); Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI); - Value *Idx = ConstantInt::get(Type::Int32Ty, 0); + Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0); Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI); if (isLoadH) { - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 0)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); } else { - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 2)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 1)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); } Value *Mask = ConstantVector::get(Idxs); SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); } else if (isMovL) { - Constant *Zero = ConstantInt::get(Type::Int32Ty, 0); + Constant *Zero = ConstantInt::get(Type::getInt32Ty(C), 0); Idxs.push_back(Zero); Idxs.push_back(Zero); Idxs.push_back(Zero); @@ -285,32 +314,33 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { Value *ZeroV = ConstantVector::get(Idxs); Idxs.clear(); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 4)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 5)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 2)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 3)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 4)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 5)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); Value *Mask = ConstantVector::get(Idxs); SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI); } else if (isMovSD || isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { Value *Op1 = CI->getOperand(2); if (isMovSD) { - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 2)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 1)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); } else if (isUnpckhPD || isPunpckhQPD) { - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 1)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 3)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); } else { - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 0)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, 2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); } Value *Mask = ConstantVector::get(Idxs); SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); } else if (isShufPD) { Value *Op1 = CI->getOperand(2); unsigned MaskVal = cast<ConstantInt>(CI->getOperand(3))->getZExtValue(); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, MaskVal & 1)); - Idxs.push_back(ConstantInt::get(Type::Int32Ty, ((MaskVal >> 1) & 1)+2)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), MaskVal & 1)); + Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), + ((MaskVal >> 1) & 1)+2)); Value *Mask = ConstantVector::get(Idxs); SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); } @@ -326,13 +356,13 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // Clean up the old call now that it has been completely upgraded. CI->eraseFromParent(); } else { - assert(0 && "Unknown function for CallInst upgrade."); + llvm_unreachable("Unknown function for CallInst upgrade."); } return; } switch (NewFn->getIntrinsicID()) { - default: assert(0 && "Unknown function for CallInst upgrade."); + default: llvm_unreachable("Unknown function for CallInst upgrade."); case Intrinsic::x86_mmx_psll_d: case Intrinsic::x86_mmx_psll_q: case Intrinsic::x86_mmx_psll_w: @@ -404,6 +434,27 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); } break; + case Intrinsic::eh_selector: + case Intrinsic::eh_typeid_for: { + // Only the return type changed. + SmallVector<Value*, 8> Operands(CI->op_begin() + 1, CI->op_end()); + CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), + "upgraded." + CI->getName(), CI); + NewCI->setTailCall(CI->isTailCall()); + NewCI->setCallingConv(CI->getCallingConv()); + + // Handle any uses of the old CallInst. + if (!CI->use_empty()) { + // Construct an appropriate cast from the new return type to the old. + CastInst *RetCast = + CastInst::Create(CastInst::getCastOpcode(NewCI, true, + F->getReturnType(), true), + NewCI, F->getReturnType(), NewCI->getName(), CI); + CI->replaceAllUsesWith(RetCast); + } + CI->eraseFromParent(); + } + break; } } @@ -428,3 +479,74 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { } } } + +/// This function checks debug info intrinsics. If an intrinsic is invalid +/// then this function simply removes the intrinsic. +void llvm::CheckDebugInfoIntrinsics(Module *M) { + + + if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { + if (!FuncStart->use_empty()) { + DbgFuncStartInst *DFSI = cast<DbgFuncStartInst>(FuncStart->use_back()); + if (!isa<MDNode>(DFSI->getOperand(1))) { + while (!FuncStart->use_empty()) { + CallInst *CI = cast<CallInst>(FuncStart->use_back()); + CI->eraseFromParent(); + } + FuncStart->eraseFromParent(); + } + } + } + + if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { + if (!StopPoint->use_empty()) { + DbgStopPointInst *DSPI = cast<DbgStopPointInst>(StopPoint->use_back()); + if (!isa<MDNode>(DSPI->getOperand(3))) { + while (!StopPoint->use_empty()) { + CallInst *CI = cast<CallInst>(StopPoint->use_back()); + CI->eraseFromParent(); + } + StopPoint->eraseFromParent(); + } + } + } + + if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { + if (!RegionStart->use_empty()) { + DbgRegionStartInst *DRSI = cast<DbgRegionStartInst>(RegionStart->use_back()); + if (!isa<MDNode>(DRSI->getOperand(1))) { + while (!RegionStart->use_empty()) { + CallInst *CI = cast<CallInst>(RegionStart->use_back()); + CI->eraseFromParent(); + } + RegionStart->eraseFromParent(); + } + } + } + + if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { + if (!RegionEnd->use_empty()) { + DbgRegionEndInst *DREI = cast<DbgRegionEndInst>(RegionEnd->use_back()); + if (!isa<MDNode>(DREI->getOperand(1))) { + while (!RegionEnd->use_empty()) { + CallInst *CI = cast<CallInst>(RegionEnd->use_back()); + CI->eraseFromParent(); + } + RegionEnd->eraseFromParent(); + } + } + } + + if (Function *Declare = M->getFunction("llvm.dbg.declare")) { + if (!Declare->use_empty()) { + DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back()); + if (!isa<MDNode>(DDI->getOperand(2))) { + while (!Declare->use_empty()) { + CallInst *CI = cast<CallInst>(Declare->use_back()); + CI->eraseFromParent(); + } + Declare->eraseFromParent(); + } + } + } +} diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 3065766362e4..50cf84c3fe62 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -14,11 +14,11 @@ #include "llvm/BasicBlock.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Type.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" #include "llvm/Support/LeakDetector.h" -#include "llvm/Support/Compiler.h" #include "SymbolTableListTraitsImpl.h" #include <algorithm> using namespace llvm; @@ -29,14 +29,18 @@ ValueSymbolTable *BasicBlock::getValueSymbolTable() { return 0; } +LLVMContext &BasicBlock::getContext() const { + return getType()->getContext(); +} + // Explicit instantiation of SymbolTableListTraits since some of the methods // are not in the public header file... template class SymbolTableListTraits<Instruction, BasicBlock>; -BasicBlock::BasicBlock(const std::string &Name, Function *NewParent, +BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::LabelTy, Value::BasicBlockVal), Parent(0) { + : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0) { // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -235,14 +239,15 @@ void BasicBlock::removePredecessor(BasicBlock *Pred, /// cause a degenerate basic block to be formed, having a terminator inside of /// the basic block). /// -BasicBlock *BasicBlock::splitBasicBlock(iterator I, const std::string &BBName) { +BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) { assert(getTerminator() && "Can't use splitBasicBlock on degenerate BB!"); assert(I != InstList.end() && "Trying to get me to create degenerate basic block!"); BasicBlock *InsertBefore = next(Function::iterator(this)) .getNodePtrUnchecked(); - BasicBlock *New = BasicBlock::Create(BBName, getParent(), InsertBefore); + BasicBlock *New = BasicBlock::Create(getContext(), BBName, + getParent(), InsertBefore); // Move all of the specified instructions from the original basic block into // the new basic block. diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt index c9cdce4789d3..9b17d4bcd210 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -13,9 +13,10 @@ add_llvm_library(LLVMCore Instruction.cpp Instructions.cpp IntrinsicInst.cpp - LeakDetector.cpp LLVMContext.cpp + LeakDetector.cpp Mangler.cpp + Metadata.cpp Module.cpp ModuleProvider.cpp Pass.cpp diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 3aab0cce37e4..c1fcc5f4ed27 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -12,9 +12,8 @@ // ConstantExpr::get* methods to automatically fold constants when possible. // // The current constant folding implementation is implemented in two pieces: the -// template-based folder for simple primitive constants like ConstantInt, and -// the special case hackery that we use to symbolically evaluate expressions -// that use ConstantExprs. +// pieces that don't need TargetData, and the pieces that do. This is to avoid +// a dependence in VMCore on Target. // //===----------------------------------------------------------------------===// @@ -24,8 +23,11 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/GlobalAlias.h" +#include "llvm/GlobalVariable.h" +#include "llvm/LLVMContext.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" @@ -39,7 +41,7 @@ using namespace llvm; /// BitCastConstantVector - Convert the specified ConstantVector node to the /// specified vector type. At this point, we know that the elements of the /// input vector constant are all simple integer or FP values. -static Constant *BitCastConstantVector(ConstantVector *CV, +static Constant *BitCastConstantVector(LLVMContext &Context, ConstantVector *CV, const VectorType *DstTy) { // If this cast changes element count then we can't handle it here: // doing so requires endianness information. This should be handled by @@ -47,7 +49,7 @@ static Constant *BitCastConstantVector(ConstantVector *CV, unsigned NumElts = DstTy->getNumElements(); if (NumElts != CV->getNumOperands()) return 0; - + // Check to verify that all elements of the input are simple. for (unsigned i = 0; i != NumElts; ++i) { if (!isa<ConstantInt>(CV->getOperand(i)) && @@ -59,7 +61,8 @@ static Constant *BitCastConstantVector(ConstantVector *CV, std::vector<Constant*> Result; const Type *DstEltTy = DstTy->getElementType(); for (unsigned i = 0; i != NumElts; ++i) - Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy)); + Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), + DstEltTy)); return ConstantVector::get(Result); } @@ -70,13 +73,13 @@ static Constant *BitCastConstantVector(ConstantVector *CV, static unsigned foldConstantCastPair( unsigned opc, ///< opcode of the second cast constant expression - const ConstantExpr*Op, ///< the first cast constant expression + ConstantExpr *Op, ///< the first cast constant expression const Type *DstTy ///< desintation type of the first cast ) { assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!"); assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type"); assert(CastInst::isCast(opc) && "Invalid cast opcode"); - + // The the types and opcodes for the two Cast constant expressions const Type *SrcTy = Op->getOperand(0)->getType(); const Type *MidTy = Op->getType(); @@ -85,41 +88,45 @@ foldConstantCastPair( // Let CastInst::isEliminableCastPair do the heavy lifting. return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, - Type::Int64Ty); + Type::getInt64Ty(DstTy->getContext())); } -static Constant *FoldBitCast(Constant *V, const Type *DestTy) { +static Constant *FoldBitCast(LLVMContext &Context, + Constant *V, const Type *DestTy) { const Type *SrcTy = V->getType(); if (SrcTy == DestTy) return V; // no-op cast - + // Check to see if we are casting a pointer to an aggregate to a pointer to // the first element. If so, return the appropriate GEP instruction. if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) if (PTy->getAddressSpace() == DPTy->getAddressSpace()) { SmallVector<Value*, 8> IdxList; - IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + Value *Zero = Constant::getNullValue(Type::getInt32Ty(Context)); + IdxList.push_back(Zero); const Type *ElTy = PTy->getElementType(); while (ElTy != DPTy->getElementType()) { if (const StructType *STy = dyn_cast<StructType>(ElTy)) { if (STy->getNumElements() == 0) break; ElTy = STy->getElementType(0); - IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + IdxList.push_back(Zero); } else if (const SequentialType *STy = dyn_cast<SequentialType>(ElTy)) { if (isa<PointerType>(ElTy)) break; // Can't index into pointers! ElTy = STy->getElementType(); - IdxList.push_back(IdxList[0]); + IdxList.push_back(Zero); } else { break; } } - + if (ElTy == DPTy->getElementType()) - return ConstantExpr::getGetElementPtr(V, &IdxList[0], IdxList.size()); + // This GEP is inbounds because all indices are zero. + return ConstantExpr::getInBoundsGetElementPtr(V, &IdxList[0], + IdxList.size()); } - + // Handle casts from one vector constant to another. We know that the src // and dest type have the same size (otherwise its an illegal cast). if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { @@ -130,48 +137,50 @@ static Constant *FoldBitCast(Constant *V, const Type *DestTy) { // First, check for null. Undef is already handled. if (isa<ConstantAggregateZero>(V)) return Constant::getNullValue(DestTy); - + if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) - return BitCastConstantVector(CV, DestPTy); + return BitCastConstantVector(Context, CV, DestPTy); } // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts // This allows for other simplifications (although some of them // can only be handled by Analysis/ConstantFolding.cpp). if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) - return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy); + return ConstantExpr::getBitCast( + ConstantVector::get(&V, 1), DestPTy); } - + // Finally, implement bitcast folding now. The code below doesn't handle // bitcast right. if (isa<ConstantPointerNull>(V)) // ptr->ptr cast. return ConstantPointerNull::get(cast<PointerType>(DestTy)); - + // Handle integral constant input. - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { if (DestTy->isInteger()) // Integral -> Integral. This is a no-op because the bit widths must // be the same. Consequently, we just fold to V. return V; if (DestTy->isFloatingPoint()) - return ConstantFP::get(APFloat(CI->getValue(), - DestTy != Type::PPC_FP128Ty)); + return ConstantFP::get(Context, APFloat(CI->getValue(), + DestTy != Type::getPPC_FP128Ty(Context))); // Otherwise, can't fold this (vector?) return 0; } // Handle ConstantFP input. - if (const ConstantFP *FP = dyn_cast<ConstantFP>(V)) + if (ConstantFP *FP = dyn_cast<ConstantFP>(V)) // FP -> Integral. - return ConstantInt::get(FP->getValueAPF().bitcastToAPInt()); + return ConstantInt::get(Context, FP->getValueAPF().bitcastToAPInt()); return 0; } -Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, +Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context, + unsigned opc, Constant *V, const Type *DestTy) { if (isa<UndefValue>(V)) { // zext(undef) = 0, because the top bits will be zero. @@ -183,12 +192,12 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, return UndefValue::get(DestTy); } // No compile-time operations on this type yet. - if (V->getType() == Type::PPC_FP128Ty || DestTy == Type::PPC_FP128Ty) + if (V->getType()->isPPC_FP128Ty() || DestTy->isPPC_FP128Ty()) return 0; // If the cast operand is a constant expression, there's a few things we can // do to try to simplify it. - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { if (CE->isCast()) { // Try hard to fold cast of cast because they are often eliminable. if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy)) @@ -211,7 +220,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, // If the cast operand is a constant vector, perform the cast by // operating on each element. In the cast of bitcasts, the element // count may be mismatched; don't attempt to handle that here. - if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) + if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) if (isa<VectorType>(DestTy) && cast<VectorType>(DestTy)->getNumElements() == CV->getType()->getNumElements()) { @@ -229,21 +238,21 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, switch (opc) { case Instruction::FPTrunc: case Instruction::FPExt: - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { + if (ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { bool ignored; APFloat Val = FPC->getValueAPF(); - Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle : - DestTy == Type::DoubleTy ? APFloat::IEEEdouble : - DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended : - DestTy == Type::FP128Ty ? APFloat::IEEEquad : + Val.convert(DestTy->isFloatTy() ? APFloat::IEEEsingle : + DestTy->isDoubleTy() ? APFloat::IEEEdouble : + DestTy->isX86_FP80Ty() ? APFloat::x87DoubleExtended : + DestTy->isFP128Ty() ? APFloat::IEEEquad : APFloat::Bogus, APFloat::rmNearestTiesToEven, &ignored); - return ConstantFP::get(Val); + return ConstantFP::get(Context, Val); } return 0; // Can't fold. case Instruction::FPToUI: case Instruction::FPToSI: - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { + if (ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { const APFloat &V = FPC->getValueAPF(); bool ignored; uint64_t x[2]; @@ -251,7 +260,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, APFloat::rmTowardZero, &ignored); APInt Val(DestBitWidth, 2, x); - return ConstantInt::get(Val); + return ConstantInt::get(Context, Val); } return 0; // Can't fold. case Instruction::IntToPtr: //always treated as unsigned @@ -264,7 +273,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, return 0; // Other pointer types cannot be casted case Instruction::UIToFP: case Instruction::SIToFP: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { APInt api = CI->getValue(); const uint64_t zero[] = {0, 0}; APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(), @@ -272,67 +281,68 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, (void)apf.convertFromAPInt(api, opc==Instruction::SIToFP, APFloat::rmNearestTiesToEven); - return ConstantFP::get(apf); + return ConstantFP::get(Context, apf); } return 0; case Instruction::ZExt: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); APInt Result(CI->getValue()); Result.zext(BitWidth); - return ConstantInt::get(Result); + return ConstantInt::get(Context, Result); } return 0; case Instruction::SExt: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); APInt Result(CI->getValue()); Result.sext(BitWidth); - return ConstantInt::get(Result); + return ConstantInt::get(Context, Result); } return 0; case Instruction::Trunc: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth(); APInt Result(CI->getValue()); Result.trunc(BitWidth); - return ConstantInt::get(Result); + return ConstantInt::get(Context, Result); } return 0; case Instruction::BitCast: - return FoldBitCast(const_cast<Constant*>(V), DestTy); + return FoldBitCast(Context, V, DestTy); default: assert(!"Invalid CE CastInst opcode"); break; } - assert(0 && "Failed to cast constant expression"); + llvm_unreachable("Failed to cast constant expression"); return 0; } -Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, - const Constant *V1, - const Constant *V2) { - if (const ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) - return const_cast<Constant*>(CB->getZExtValue() ? V1 : V2); +Constant *llvm::ConstantFoldSelectInstruction(LLVMContext&, + Constant *Cond, + Constant *V1, Constant *V2) { + if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) + return CB->getZExtValue() ? V1 : V2; - if (isa<UndefValue>(V1)) return const_cast<Constant*>(V2); - if (isa<UndefValue>(V2)) return const_cast<Constant*>(V1); - if (isa<UndefValue>(Cond)) return const_cast<Constant*>(V1); - if (V1 == V2) return const_cast<Constant*>(V1); + if (isa<UndefValue>(V1)) return V2; + if (isa<UndefValue>(V2)) return V1; + if (isa<UndefValue>(Cond)) return V1; + if (V1 == V2) return V1; return 0; } -Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, - const Constant *Idx) { +Constant *llvm::ConstantFoldExtractElementInstruction(LLVMContext &Context, + Constant *Val, + Constant *Idx) { if (isa<UndefValue>(Val)) // ee(undef, x) -> undef return UndefValue::get(cast<VectorType>(Val->getType())->getElementType()); if (Val->isNullValue()) // ee(zero, x) -> zero return Constant::getNullValue( cast<VectorType>(Val->getType())->getElementType()); - - if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) { - if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) { + + if (ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) { + if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) { return CVal->getOperand(CIdx->getZExtValue()); } else if (isa<UndefValue>(Idx)) { // ee({w,x,y,z}, undef) -> w (an arbitrary value). @@ -342,17 +352,18 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, return 0; } -Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, - const Constant *Elt, - const Constant *Idx) { - const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); +Constant *llvm::ConstantFoldInsertElementInstruction(LLVMContext &Context, + Constant *Val, + Constant *Elt, + Constant *Idx) { + ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx); if (!CIdx) return 0; APInt idxVal = CIdx->getValue(); if (isa<UndefValue>(Val)) { // Insertion of scalar constant into vector undef // Optimize away insertion of undef if (isa<UndefValue>(Elt)) - return const_cast<Constant*>(Val); + return Val; // Otherwise break the aggregate undef into multiple undefs and do // the insertion unsigned numOps = @@ -360,9 +371,9 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, std::vector<Constant*> Ops; Ops.reserve(numOps); for (unsigned i = 0; i < numOps; ++i) { - const Constant *Op = + Constant *Op = (idxVal == i) ? Elt : UndefValue::get(Elt->getType()); - Ops.push_back(const_cast<Constant*>(Op)); + Ops.push_back(Op); } return ConstantVector::get(Ops); } @@ -370,7 +381,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, // Insertion of scalar constant into vector aggregate zero // Optimize away insertion of zero if (Elt->isNullValue()) - return const_cast<Constant*>(Val); + return Val; // Otherwise break the aggregate zero into multiple zeros and do // the insertion unsigned numOps = @@ -378,20 +389,20 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, std::vector<Constant*> Ops; Ops.reserve(numOps); for (unsigned i = 0; i < numOps; ++i) { - const Constant *Op = + Constant *Op = (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType()); - Ops.push_back(const_cast<Constant*>(Op)); + Ops.push_back(Op); } return ConstantVector::get(Ops); } - if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) { + if (ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) { // Insertion of scalar constant into vector constant std::vector<Constant*> Ops; Ops.reserve(CVal->getNumOperands()); for (unsigned i = 0; i < CVal->getNumOperands(); ++i) { - const Constant *Op = + Constant *Op = (idxVal == i) ? Elt : cast<Constant>(CVal->getOperand(i)); - Ops.push_back(const_cast<Constant*>(Op)); + Ops.push_back(Op); } return ConstantVector::get(Ops); } @@ -401,10 +412,11 @@ Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, /// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef /// return the specified element value. Otherwise return null. -static Constant *GetVectorElement(const Constant *C, unsigned EltNo) { - if (const ConstantVector *CV = dyn_cast<ConstantVector>(C)) +static Constant *GetVectorElement(LLVMContext &Context, Constant *C, + unsigned EltNo) { + if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) return CV->getOperand(EltNo); - + const Type *EltTy = cast<VectorType>(C->getType())->getElementType(); if (isa<ConstantAggregateZero>(C)) return Constant::getNullValue(EltTy); @@ -413,9 +425,10 @@ static Constant *GetVectorElement(const Constant *C, unsigned EltNo) { return 0; } -Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, - const Constant *V2, - const Constant *Mask) { +Constant *llvm::ConstantFoldShuffleVectorInstruction(LLVMContext &Context, + Constant *V1, + Constant *V2, + Constant *Mask) { // Undefined shuffle mask -> undefined value. if (isa<UndefValue>(Mask)) return UndefValue::get(V1->getType()); @@ -426,7 +439,7 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, // Loop over the shuffle mask, evaluating each element. SmallVector<Constant*, 32> Result; for (unsigned i = 0; i != MaskNumElts; ++i) { - Constant *InElt = GetVectorElement(Mask, i); + Constant *InElt = GetVectorElement(Context, Mask, i); if (InElt == 0) return 0; if (isa<UndefValue>(InElt)) @@ -436,9 +449,9 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, if (Elt >= SrcNumElts*2) InElt = UndefValue::get(EltTy); else if (Elt >= SrcNumElts) - InElt = GetVectorElement(V2, Elt - SrcNumElts); + InElt = GetVectorElement(Context, V2, Elt - SrcNumElts); else - InElt = GetVectorElement(V1, Elt); + InElt = GetVectorElement(Context, V1, Elt); if (InElt == 0) return 0; } else { // Unknown value. @@ -450,12 +463,13 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, return ConstantVector::get(&Result[0], Result.size()); } -Constant *llvm::ConstantFoldExtractValueInstruction(const Constant *Agg, +Constant *llvm::ConstantFoldExtractValueInstruction(LLVMContext &Context, + Constant *Agg, const unsigned *Idxs, unsigned NumIdx) { // Base case: no indices, so return the entire value. if (NumIdx == 0) - return const_cast<Constant *>(Agg); + return Agg; if (isa<UndefValue>(Agg)) // ev(undef, x) -> undef return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(), @@ -469,123 +483,111 @@ Constant *llvm::ConstantFoldExtractValueInstruction(const Constant *Agg, Idxs + NumIdx)); // Otherwise recurse. - return ConstantFoldExtractValueInstruction(Agg->getOperand(*Idxs), + return ConstantFoldExtractValueInstruction(Context, Agg->getOperand(*Idxs), Idxs+1, NumIdx-1); } -Constant *llvm::ConstantFoldInsertValueInstruction(const Constant *Agg, - const Constant *Val, +Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, + Constant *Agg, + Constant *Val, const unsigned *Idxs, unsigned NumIdx) { // Base case: no indices, so replace the entire value. if (NumIdx == 0) - return const_cast<Constant *>(Val); + return Val; if (isa<UndefValue>(Agg)) { // Insertion of constant into aggregate undef - // Optimize away insertion of undef + // Optimize away insertion of undef. if (isa<UndefValue>(Val)) - return const_cast<Constant*>(Agg); + return Agg; + // Otherwise break the aggregate undef into multiple undefs and do - // the insertion + // the insertion. const CompositeType *AggTy = cast<CompositeType>(Agg->getType()); unsigned numOps; if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy)) numOps = AR->getNumElements(); else numOps = cast<StructType>(AggTy)->getNumElements(); + std::vector<Constant*> Ops(numOps); for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); - const Constant *Op = + Constant *Op = (*Idxs == i) ? - ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy), + ConstantFoldInsertValueInstruction(Context, UndefValue::get(MemberTy), Val, Idxs+1, NumIdx-1) : UndefValue::get(MemberTy); - Ops[i] = const_cast<Constant*>(Op); + Ops[i] = Op; } - if (isa<StructType>(AggTy)) - return ConstantStruct::get(Ops); - else - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); + + if (const StructType* ST = dyn_cast<StructType>(AggTy)) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } + if (isa<ConstantAggregateZero>(Agg)) { // Insertion of constant into aggregate zero - // Optimize away insertion of zero + // Optimize away insertion of zero. if (Val->isNullValue()) - return const_cast<Constant*>(Agg); + return Agg; + // Otherwise break the aggregate zero into multiple zeros and do - // the insertion + // the insertion. const CompositeType *AggTy = cast<CompositeType>(Agg->getType()); unsigned numOps; if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy)) numOps = AR->getNumElements(); else numOps = cast<StructType>(AggTy)->getNumElements(); + std::vector<Constant*> Ops(numOps); for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); - const Constant *Op = + Constant *Op = (*Idxs == i) ? - ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy), + ConstantFoldInsertValueInstruction(Context, + Constant::getNullValue(MemberTy), Val, Idxs+1, NumIdx-1) : Constant::getNullValue(MemberTy); - Ops[i] = const_cast<Constant*>(Op); + Ops[i] = Op; } - if (isa<StructType>(AggTy)) - return ConstantStruct::get(Ops); - else - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); + + if (const StructType* ST = dyn_cast<StructType>(AggTy)) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } + if (isa<ConstantStruct>(Agg) || isa<ConstantArray>(Agg)) { - // Insertion of constant into aggregate constant + // Insertion of constant into aggregate constant. std::vector<Constant*> Ops(Agg->getNumOperands()); for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { - const Constant *Op = + Constant *Op = (*Idxs == i) ? - ConstantFoldInsertValueInstruction(Agg->getOperand(i), + ConstantFoldInsertValueInstruction(Context, Agg->getOperand(i), Val, Idxs+1, NumIdx-1) : Agg->getOperand(i); - Ops[i] = const_cast<Constant*>(Op); + Ops[i] = Op; } - Constant *C; - if (isa<StructType>(Agg->getType())) - C = ConstantStruct::get(Ops); - else - C = ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); - return C; + + if (const StructType* ST = dyn_cast<StructType>(Agg->getType())) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); } return 0; } -/// EvalVectorOp - Given two vector constants and a function pointer, apply the -/// function pointer to each element pair, producing a new ConstantVector -/// constant. Either or both of V1 and V2 may be NULL, meaning a -/// ConstantAggregateZero operand. -static Constant *EvalVectorOp(const ConstantVector *V1, - const ConstantVector *V2, - const VectorType *VTy, - Constant *(*FP)(Constant*, Constant*)) { - std::vector<Constant*> Res; - const Type *EltTy = VTy->getElementType(); - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - const Constant *C1 = V1 ? V1->getOperand(i) : Constant::getNullValue(EltTy); - const Constant *C2 = V2 ? V2->getOperand(i) : Constant::getNullValue(EltTy); - Res.push_back(FP(const_cast<Constant*>(C1), - const_cast<Constant*>(C2))); - } - return ConstantVector::get(Res); -} -Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, - const Constant *C1, - const Constant *C2) { +Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context, + unsigned Opcode, + Constant *C1, Constant *C2) { // No compile-time operations on this type yet. - if (C1->getType() == Type::PPC_FP128Ty) + if (C1->getType()->isPPC_FP128Ty()) return 0; - // Handle UndefValue up front + // Handle UndefValue up front. if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) { switch (Opcode) { case Instruction::Xor: @@ -606,23 +608,23 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::SRem: if (!isa<UndefValue>(C2)) // undef / X -> 0 return Constant::getNullValue(C1->getType()); - return const_cast<Constant*>(C2); // X / undef -> undef + return C2; // X / undef -> undef case Instruction::Or: // X | undef -> -1 if (const VectorType *PTy = dyn_cast<VectorType>(C1->getType())) - return ConstantVector::getAllOnesValue(PTy); - return ConstantInt::getAllOnesValue(C1->getType()); + return Constant::getAllOnesValue(PTy); + return Constant::getAllOnesValue(C1->getType()); case Instruction::LShr: if (isa<UndefValue>(C2) && isa<UndefValue>(C1)) - return const_cast<Constant*>(C1); // undef lshr undef -> undef + return C1; // undef lshr undef -> undef return Constant::getNullValue(C1->getType()); // X lshr undef -> 0 // undef lshr X -> 0 case Instruction::AShr: if (!isa<UndefValue>(C2)) - return const_cast<Constant*>(C1); // undef ashr X --> undef + return C1; // undef ashr X --> undef else if (isa<UndefValue>(C1)) - return const_cast<Constant*>(C1); // undef ashr undef -> undef + return C1; // undef ashr undef -> undef else - return const_cast<Constant*>(C1); // X ashr undef --> X + return C1; // X ashr undef --> X case Instruction::Shl: // undef << X -> 0 or X << undef -> 0 return Constant::getNullValue(C1->getType()); @@ -630,23 +632,23 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } // Handle simplifications when the RHS is a constant int. - if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) { + if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) { switch (Opcode) { case Instruction::Add: - if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X + 0 == X + if (CI2->equalsInt(0)) return C1; // X + 0 == X break; case Instruction::Sub: - if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X - 0 == X + if (CI2->equalsInt(0)) return C1; // X - 0 == X break; case Instruction::Mul: - if (CI2->equalsInt(0)) return const_cast<Constant*>(C2); // X * 0 == 0 + if (CI2->equalsInt(0)) return C2; // X * 0 == 0 if (CI2->equalsInt(1)) - return const_cast<Constant*>(C1); // X * 1 == X + return C1; // X * 1 == X break; case Instruction::UDiv: case Instruction::SDiv: if (CI2->equalsInt(1)) - return const_cast<Constant*>(C1); // X / 1 == X + return C1; // X / 1 == X if (CI2->equalsInt(0)) return UndefValue::get(CI2->getType()); // X / 0 == undef break; @@ -658,11 +660,11 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, return UndefValue::get(CI2->getType()); // X % 0 == undef break; case Instruction::And: - if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0 + if (CI2->isZero()) return C2; // X & 0 == 0 if (CI2->isAllOnesValue()) - return const_cast<Constant*>(C1); // X & -1 == X - - if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { + return C1; // X & -1 == X + + if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { // (zext i32 to i64) & 4294967295 -> (zext i32 to i64) if (CE1->getOpcode() == Instruction::ZExt) { unsigned DstWidth = CI2->getType()->getBitWidth(); @@ -670,19 +672,19 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, CE1->getOperand(0)->getType()->getPrimitiveSizeInBits(); APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth)); if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits) - return const_cast<Constant*>(C1); + return C1; } - + // If and'ing the address of a global with a constant, fold it. if (CE1->getOpcode() == Instruction::PtrToInt && isa<GlobalValue>(CE1->getOperand(0))) { GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0)); - + // Functions are at least 4-byte aligned. unsigned GVAlign = GV->getAlignment(); if (isa<Function>(GV)) GVAlign = std::max(GVAlign, 4U); - + if (GVAlign > 1) { unsigned DstWidth = CI2->getType()->getBitWidth(); unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign)); @@ -696,26 +698,39 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } break; case Instruction::Or: - if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X | 0 == X + if (CI2->equalsInt(0)) return C1; // X | 0 == X if (CI2->isAllOnesValue()) - return const_cast<Constant*>(C2); // X | -1 == -1 + return C2; // X | -1 == -1 break; case Instruction::Xor: - if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X ^ 0 == X + if (CI2->equalsInt(0)) return C1; // X ^ 0 == X + + if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { + switch (CE1->getOpcode()) { + default: break; + case Instruction::ICmp: + case Instruction::FCmp: + // cmp pred ^ true -> cmp !pred + assert(CI2->equalsInt(1)); + CmpInst::Predicate pred = (CmpInst::Predicate)CE1->getPredicate(); + pred = CmpInst::getInversePredicate(pred); + return ConstantExpr::getCompare(pred, CE1->getOperand(0), + CE1->getOperand(1)); + } + } break; case Instruction::AShr: // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2 - if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) + if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero. - return ConstantExpr::getLShr(const_cast<Constant*>(C1), - const_cast<Constant*>(C2)); + return ConstantExpr::getLShr(C1, C2); break; } } - + // At this point we know neither constant is an UndefValue. - if (const ConstantInt *CI1 = dyn_cast<ConstantInt>(C1)) { - if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) { + if (ConstantInt *CI1 = dyn_cast<ConstantInt>(C1)) { + if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) { using namespace APIntOps; const APInt &C1V = CI1->getValue(); const APInt &C2V = CI2->getValue(); @@ -723,51 +738,51 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, default: break; case Instruction::Add: - return ConstantInt::get(C1V + C2V); + return ConstantInt::get(Context, C1V + C2V); case Instruction::Sub: - return ConstantInt::get(C1V - C2V); + return ConstantInt::get(Context, C1V - C2V); case Instruction::Mul: - return ConstantInt::get(C1V * C2V); + return ConstantInt::get(Context, C1V * C2V); case Instruction::UDiv: assert(!CI2->isNullValue() && "Div by zero handled above"); - return ConstantInt::get(C1V.udiv(C2V)); + return ConstantInt::get(Context, C1V.udiv(C2V)); case Instruction::SDiv: assert(!CI2->isNullValue() && "Div by zero handled above"); if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) return UndefValue::get(CI1->getType()); // MIN_INT / -1 -> undef - return ConstantInt::get(C1V.sdiv(C2V)); + return ConstantInt::get(Context, C1V.sdiv(C2V)); case Instruction::URem: assert(!CI2->isNullValue() && "Div by zero handled above"); - return ConstantInt::get(C1V.urem(C2V)); + return ConstantInt::get(Context, C1V.urem(C2V)); case Instruction::SRem: assert(!CI2->isNullValue() && "Div by zero handled above"); if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) return UndefValue::get(CI1->getType()); // MIN_INT % -1 -> undef - return ConstantInt::get(C1V.srem(C2V)); + return ConstantInt::get(Context, C1V.srem(C2V)); case Instruction::And: - return ConstantInt::get(C1V & C2V); + return ConstantInt::get(Context, C1V & C2V); case Instruction::Or: - return ConstantInt::get(C1V | C2V); + return ConstantInt::get(Context, C1V | C2V); case Instruction::Xor: - return ConstantInt::get(C1V ^ C2V); + return ConstantInt::get(Context, C1V ^ C2V); case Instruction::Shl: { uint32_t shiftAmt = C2V.getZExtValue(); if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.shl(shiftAmt)); + return ConstantInt::get(Context, C1V.shl(shiftAmt)); else return UndefValue::get(C1->getType()); // too big shift is undef } case Instruction::LShr: { uint32_t shiftAmt = C2V.getZExtValue(); if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.lshr(shiftAmt)); + return ConstantInt::get(Context, C1V.lshr(shiftAmt)); else return UndefValue::get(C1->getType()); // too big shift is undef } case Instruction::AShr: { uint32_t shiftAmt = C2V.getZExtValue(); if (shiftAmt < C1V.getBitWidth()) - return ConstantInt::get(C1V.ashr(shiftAmt)); + return ConstantInt::get(Context, C1V.ashr(shiftAmt)); else return UndefValue::get(C1->getType()); // too big shift is undef } @@ -782,13 +797,13 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::LShr: case Instruction::AShr: case Instruction::Shl: - if (CI1->equalsInt(0)) return const_cast<Constant*>(C1); + if (CI1->equalsInt(0)) return C1; break; default: break; } - } else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) { - if (const ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) { + } else if (ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) { + if (ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) { APFloat C1V = CFP1->getValueAPF(); APFloat C2V = CFP2->getValueAPF(); APFloat C3V = C1V; // copy for modification @@ -797,65 +812,159 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, break; case Instruction::FAdd: (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C3V); + return ConstantFP::get(Context, C3V); case Instruction::FSub: (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C3V); + return ConstantFP::get(Context, C3V); case Instruction::FMul: (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C3V); + return ConstantFP::get(Context, C3V); case Instruction::FDiv: (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C3V); + return ConstantFP::get(Context, C3V); case Instruction::FRem: (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven); - return ConstantFP::get(C3V); + return ConstantFP::get(Context, C3V); } } } else if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType())) { - const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1); - const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2); + ConstantVector *CP1 = dyn_cast<ConstantVector>(C1); + ConstantVector *CP2 = dyn_cast<ConstantVector>(C2); if ((CP1 != NULL || isa<ConstantAggregateZero>(C1)) && (CP2 != NULL || isa<ConstantAggregateZero>(C2))) { + std::vector<Constant*> Res; + const Type* EltTy = VTy->getElementType(); + Constant *C1 = 0; + Constant *C2 = 0; switch (Opcode) { default: break; case Instruction::Add: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getAdd(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::FAdd: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFAdd); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getFAdd(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::Sub: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getSub(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::FSub: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFSub); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getFSub(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::Mul: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getMul(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::FMul: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFMul); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getFMul(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::UDiv: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getUDiv(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::SDiv: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSDiv); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getSDiv(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::FDiv: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFDiv); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getFDiv(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::URem: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getURem); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getURem(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::SRem: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSRem); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getSRem(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::FRem: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFRem); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getFRem(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::And: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAnd); - case Instruction::Or: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr); - case Instruction::Xor: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getAnd(C1, C2)); + } + return ConstantVector::get(Res); + case Instruction::Or: + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getOr(C1, C2)); + } + return ConstantVector::get(Res); + case Instruction::Xor: + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getXor(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::LShr: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getLShr); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getLShr(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::AShr: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAShr); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getAShr(C1, C2)); + } + return ConstantVector::get(Res); case Instruction::Shl: - return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getShl); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + C1 = CP1 ? CP1->getOperand(i) : Constant::getNullValue(EltTy); + C2 = CP2 ? CP2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(ConstantExpr::getShl(C1, C2)); + } + return ConstantVector::get(Res); } } } @@ -876,8 +985,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::Or: case Instruction::Xor: // No change of opcode required. - return ConstantFoldBinaryInstruction(Opcode, C2, C1); - + return ConstantFoldBinaryInstruction(Context, Opcode, C2, C1); + case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: @@ -893,7 +1002,36 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, break; } } - + + // i1 can be simplified in many cases. + if (C1->getType() == Type::getInt1Ty(Context)) { + switch (Opcode) { + case Instruction::Add: + case Instruction::Sub: + return ConstantExpr::getXor(C1, C2); + case Instruction::Mul: + return ConstantExpr::getAnd(C1, C2); + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + // We can assume that C2 == 0. If it were one the result would be + // undefined because the shift value is as large as the bitwidth. + return C1; + case Instruction::SDiv: + case Instruction::UDiv: + // We can assume that C2 == 1. If it were zero the result would be + // undefined through division by zero. + return C1; + case Instruction::URem: + case Instruction::SRem: + // We can assume that C2 == 1. If it were zero the result would be + // undefined through division by zero. + return ConstantInt::getFalse(Context); + default: + break; + } + } + // We don't know how to fold this. return 0; } @@ -922,7 +1060,8 @@ static bool isMaybeZeroSizedType(const Type *Ty) { /// first is less than the second, return -1, if the second is less than the /// first, return 1. If the constants are not integral, return -2. /// -static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { +static int IdxCompare(LLVMContext &Context, Constant *C1, Constant *C2, + const Type *ElTy) { if (C1 == C2) return 0; // Ok, we found a different index. If they are not ConstantInt, we can't do @@ -932,11 +1071,11 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { // Ok, we have two differing integer indices. Sign extend them to be the same // type. Long is always big enough, so we use it. - if (C1->getType() != Type::Int64Ty) - C1 = ConstantExpr::getSExt(C1, Type::Int64Ty); + if (C1->getType() != Type::getInt64Ty(Context)) + C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(Context)); - if (C2->getType() != Type::Int64Ty) - C2 = ConstantExpr::getSExt(C2, Type::Int64Ty); + if (C2->getType() != Type::getInt64Ty(Context)) + C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(Context)); if (C1 == C2) return 0; // They are equal @@ -965,13 +1104,13 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { /// To simplify this code we canonicalize the relation so that the first /// operand is always the most "complex" of the two. We consider ConstantFP /// to be the simplest, and ConstantExprs to be the most complex. -static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1, - const Constant *V2) { +static FCmpInst::Predicate evaluateFCmpRelation(LLVMContext &Context, + Constant *V1, Constant *V2) { assert(V1->getType() == V2->getType() && "Cannot compare values of different types!"); // No compile-time operations on this type yet. - if (V1->getType() == Type::PPC_FP128Ty) + if (V1->getType()->isPPC_FP128Ty()) return FCmpInst::BAD_FCMP_PREDICATE; // Handle degenerate case quickly @@ -981,33 +1120,31 @@ static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1, if (!isa<ConstantExpr>(V2)) { // We distilled thisUse the standard constant folder for a few cases ConstantInt *R = 0; - Constant *C1 = const_cast<Constant*>(V1); - Constant *C2 = const_cast<Constant*>(V2); R = dyn_cast<ConstantInt>( - ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, C1, C2)); + ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, V1, V2)); if (R && !R->isZero()) return FCmpInst::FCMP_OEQ; R = dyn_cast<ConstantInt>( - ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, C1, C2)); + ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, V1, V2)); if (R && !R->isZero()) return FCmpInst::FCMP_OLT; R = dyn_cast<ConstantInt>( - ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, C1, C2)); + ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, V1, V2)); if (R && !R->isZero()) return FCmpInst::FCMP_OGT; // Nothing more we can do return FCmpInst::BAD_FCMP_PREDICATE; } - + // If the first operand is simple and second is ConstantExpr, swap operands. - FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(V2, V1); + FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(Context, V2, V1); if (SwappedRelation != FCmpInst::BAD_FCMP_PREDICATE) return FCmpInst::getSwappedPredicate(SwappedRelation); } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr or a simple constant. - const ConstantExpr *CE1 = cast<ConstantExpr>(V1); + ConstantExpr *CE1 = cast<ConstantExpr>(V1); switch (CE1->getOpcode()) { case Instruction::FPTrunc: case Instruction::FPExt: @@ -1036,8 +1173,9 @@ static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1, /// constants (like ConstantInt) to be the simplest, followed by /// GlobalValues, followed by ConstantExpr's (the most complex). /// -static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, - const Constant *V2, +static ICmpInst::Predicate evaluateICmpRelation(LLVMContext &Context, + Constant *V1, + Constant *V2, bool isSigned) { assert(V1->getType() == V2->getType() && "Cannot compare different types of values!"); @@ -1048,35 +1186,33 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, // We distilled this down to a simple case, use the standard constant // folder. ConstantInt *R = 0; - Constant *C1 = const_cast<Constant*>(V1); - Constant *C2 = const_cast<Constant*>(V2); ICmpInst::Predicate pred = ICmpInst::ICMP_EQ; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2)); + R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); if (R && !R->isZero()) return pred; pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2)); + R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); if (R && !R->isZero()) return pred; - pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; - R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2)); + pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, V1, V2)); if (R && !R->isZero()) return pred; - + // If we couldn't figure it out, bail. return ICmpInst::BAD_ICMP_PREDICATE; } - + // If the first operand is simple, swap operands. ICmpInst::Predicate SwappedRelation = - evaluateICmpRelation(V2, V1, isSigned); + evaluateICmpRelation(Context, V2, V1, isSigned); if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) return ICmpInst::getSwappedPredicate(SwappedRelation); } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)) { if (isa<ConstantExpr>(V2)) { // Swap as necessary. ICmpInst::Predicate SwappedRelation = - evaluateICmpRelation(V2, V1, isSigned); + evaluateICmpRelation(Context, V2, V1, isSigned); if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) return ICmpInst::getSwappedPredicate(SwappedRelation); else @@ -1099,8 +1235,8 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr, a CPR, or a simple constant. - const ConstantExpr *CE1 = cast<ConstantExpr>(V1); - const Constant *CE1Op0 = CE1->getOperand(0); + ConstantExpr *CE1 = cast<ConstantExpr>(V1); + Constant *CE1Op0 = CE1->getOperand(0); switch (CE1->getOpcode()) { case Instruction::Trunc: @@ -1119,28 +1255,12 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, // null pointer, do the comparison with the pre-casted value. if (V2->isNullValue() && (isa<PointerType>(CE1->getType()) || CE1->getType()->isInteger())) { - bool sgnd = isSigned; if (CE1->getOpcode() == Instruction::ZExt) isSigned = false; if (CE1->getOpcode() == Instruction::SExt) isSigned = true; - return evaluateICmpRelation(CE1Op0, + return evaluateICmpRelation(Context, CE1Op0, Constant::getNullValue(CE1Op0->getType()), - sgnd); + isSigned); } - - // If the dest type is a pointer type, and the RHS is a constantexpr cast - // from the same type as the src of the LHS, evaluate the inputs. This is - // important for things like "icmp eq (cast 4 to int*), (cast 5 to int*)", - // which happens a lot in compilers with tagged integers. - if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2)) - if (CE2->isCast() && isa<PointerType>(CE1->getType()) && - CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() && - CE1->getOperand(0)->getType()->isInteger()) { - bool sgnd = isSigned; - if (CE1->getOpcode() == Instruction::ZExt) isSigned = false; - if (CE1->getOpcode() == Instruction::SExt) isSigned = true; - return evaluateICmpRelation(CE1->getOperand(0), CE2->getOperand(0), - sgnd); - } break; case Instruction::GetElementPtr: @@ -1157,7 +1277,7 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, else // If its not weak linkage, the GVal must have a non-zero address // so the result is greater-than - return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; } else if (isa<ConstantPointerNull>(CE1Op0)) { // If we are indexing from a null pointer, check to see if we have any // non-zero indices. @@ -1196,8 +1316,8 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, } } } else { - const ConstantExpr *CE2 = cast<ConstantExpr>(V2); - const Constant *CE2Op0 = CE2->getOperand(0); + ConstantExpr *CE2 = cast<ConstantExpr>(V2); + Constant *CE2Op0 = CE2->getOperand(0); // There are MANY other foldings that we could perform here. They will // probably be added on demand, as they seem needed. @@ -1214,12 +1334,20 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, // ordering of the resultant pointers. unsigned i = 1; + // The logic below assumes that the result of the comparison + // can be determined by finding the first index that differs. + // This doesn't work if there is over-indexing in any + // subsequent indices, so check for that case first. + if (!CE1->isGEPWithNoNotionalOverIndexing() || + !CE2->isGEPWithNoNotionalOverIndexing()) + return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal. + // Compare all of the operands the GEP's have in common. gep_type_iterator GTI = gep_type_begin(CE1); for (;i != CE1->getNumOperands() && i != CE2->getNumOperands(); ++i, ++GTI) - switch (IdxCompare(CE1->getOperand(i), CE2->getOperand(i), - GTI.getIndexedType())) { + switch (IdxCompare(Context, CE1->getOperand(i), + CE2->getOperand(i), GTI.getIndexedType())) { case -1: return isSigned ? ICmpInst::ICMP_SLT:ICmpInst::ICMP_ULT; case 1: return isSigned ? ICmpInst::ICMP_SGT:ICmpInst::ICMP_UGT; case -2: return ICmpInst::BAD_ICMP_PREDICATE; @@ -1254,36 +1382,28 @@ static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, return ICmpInst::BAD_ICMP_PREDICATE; } -Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, - const Constant *C1, - const Constant *C2) { +Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context, + unsigned short pred, + Constant *C1, Constant *C2) { + const Type *ResultTy; + if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) + ResultTy = VectorType::get(Type::getInt1Ty(Context), VT->getNumElements()); + else + ResultTy = Type::getInt1Ty(Context); + // Fold FCMP_FALSE/FCMP_TRUE unconditionally. - if (pred == FCmpInst::FCMP_FALSE) { - if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) - return Constant::getNullValue(VectorType::getInteger(VT)); - else - return ConstantInt::getFalse(); - } - - if (pred == FCmpInst::FCMP_TRUE) { - if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) - return Constant::getAllOnesValue(VectorType::getInteger(VT)); - else - return ConstantInt::getTrue(); - } - + if (pred == FCmpInst::FCMP_FALSE) + return Constant::getNullValue(ResultTy); + + if (pred == FCmpInst::FCMP_TRUE) + return Constant::getAllOnesValue(ResultTy); + // Handle some degenerate cases first - if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) { - // vicmp/vfcmp -> [vector] undef - if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType())) - return UndefValue::get(VectorType::getInteger(VTy)); - - // icmp/fcmp -> i1 undef - return UndefValue::get(Type::Int1Ty); - } + if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) + return UndefValue::get(ResultTy); // No compile-time operations on this type yet. - if (C1->getType() == Type::PPC_FP128Ty) + if (C1->getType()->isPPC_FP128Ty()) return 0; // icmp eq/ne(null,GV) -> false/true @@ -1292,9 +1412,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, // Don't try to evaluate aliases. External weak GV can be null. if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) { if (pred == ICmpInst::ICMP_EQ) - return ConstantInt::getFalse(); + return ConstantInt::getFalse(Context); else if (pred == ICmpInst::ICMP_NE) - return ConstantInt::getTrue(); + return ConstantInt::getTrue(Context); } // icmp eq/ne(GV,null) -> false/true } else if (C2->isNullValue()) { @@ -1302,114 +1422,115 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, // Don't try to evaluate aliases. External weak GV can be null. if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) { if (pred == ICmpInst::ICMP_EQ) - return ConstantInt::getFalse(); + return ConstantInt::getFalse(Context); else if (pred == ICmpInst::ICMP_NE) - return ConstantInt::getTrue(); + return ConstantInt::getTrue(Context); } } + // If the comparison is a comparison between two i1's, simplify it. + if (C1->getType() == Type::getInt1Ty(Context)) { + switch(pred) { + case ICmpInst::ICMP_EQ: + if (isa<ConstantInt>(C2)) + return ConstantExpr::getXor(C1, ConstantExpr::getNot(C2)); + return ConstantExpr::getXor(ConstantExpr::getNot(C1), C2); + case ICmpInst::ICMP_NE: + return ConstantExpr::getXor(C1, C2); + default: + break; + } + } + if (isa<ConstantInt>(C1) && isa<ConstantInt>(C2)) { APInt V1 = cast<ConstantInt>(C1)->getValue(); APInt V2 = cast<ConstantInt>(C2)->getValue(); switch (pred) { - default: assert(0 && "Invalid ICmp Predicate"); return 0; - case ICmpInst::ICMP_EQ: return ConstantInt::get(Type::Int1Ty, V1 == V2); - case ICmpInst::ICMP_NE: return ConstantInt::get(Type::Int1Ty, V1 != V2); - case ICmpInst::ICMP_SLT:return ConstantInt::get(Type::Int1Ty, V1.slt(V2)); - case ICmpInst::ICMP_SGT:return ConstantInt::get(Type::Int1Ty, V1.sgt(V2)); - case ICmpInst::ICMP_SLE:return ConstantInt::get(Type::Int1Ty, V1.sle(V2)); - case ICmpInst::ICMP_SGE:return ConstantInt::get(Type::Int1Ty, V1.sge(V2)); - case ICmpInst::ICMP_ULT:return ConstantInt::get(Type::Int1Ty, V1.ult(V2)); - case ICmpInst::ICMP_UGT:return ConstantInt::get(Type::Int1Ty, V1.ugt(V2)); - case ICmpInst::ICMP_ULE:return ConstantInt::get(Type::Int1Ty, V1.ule(V2)); - case ICmpInst::ICMP_UGE:return ConstantInt::get(Type::Int1Ty, V1.uge(V2)); + default: llvm_unreachable("Invalid ICmp Predicate"); return 0; + case ICmpInst::ICMP_EQ: + return ConstantInt::get(Type::getInt1Ty(Context), V1 == V2); + case ICmpInst::ICMP_NE: + return ConstantInt::get(Type::getInt1Ty(Context), V1 != V2); + case ICmpInst::ICMP_SLT: + return ConstantInt::get(Type::getInt1Ty(Context), V1.slt(V2)); + case ICmpInst::ICMP_SGT: + return ConstantInt::get(Type::getInt1Ty(Context), V1.sgt(V2)); + case ICmpInst::ICMP_SLE: + return ConstantInt::get(Type::getInt1Ty(Context), V1.sle(V2)); + case ICmpInst::ICMP_SGE: + return ConstantInt::get(Type::getInt1Ty(Context), V1.sge(V2)); + case ICmpInst::ICMP_ULT: + return ConstantInt::get(Type::getInt1Ty(Context), V1.ult(V2)); + case ICmpInst::ICMP_UGT: + return ConstantInt::get(Type::getInt1Ty(Context), V1.ugt(V2)); + case ICmpInst::ICMP_ULE: + return ConstantInt::get(Type::getInt1Ty(Context), V1.ule(V2)); + case ICmpInst::ICMP_UGE: + return ConstantInt::get(Type::getInt1Ty(Context), V1.uge(V2)); } } else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) { APFloat C1V = cast<ConstantFP>(C1)->getValueAPF(); APFloat C2V = cast<ConstantFP>(C2)->getValueAPF(); APFloat::cmpResult R = C1V.compare(C2V); switch (pred) { - default: assert(0 && "Invalid FCmp Predicate"); return 0; - case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse(); - case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue(); + default: llvm_unreachable("Invalid FCmp Predicate"); return 0; + case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse(Context); + case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue(Context); case FCmpInst::FCMP_UNO: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered); + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered); case FCmpInst::FCMP_ORD: - return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpUnordered); + return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpUnordered); case FCmpInst::FCMP_UEQ: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered || R==APFloat::cmpEqual); case FCmpInst::FCMP_OEQ: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpEqual); + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpEqual); case FCmpInst::FCMP_UNE: - return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpEqual); + return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpEqual); case FCmpInst::FCMP_ONE: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan || R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_ULT: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered || R==APFloat::cmpLessThan); case FCmpInst::FCMP_OLT: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan); + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan); case FCmpInst::FCMP_UGT: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpUnordered || R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_OGT: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan); + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_ULE: - return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpGreaterThan); + return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpGreaterThan); case FCmpInst::FCMP_OLE: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpLessThan || R==APFloat::cmpEqual); case FCmpInst::FCMP_UGE: - return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpLessThan); + return ConstantInt::get(Type::getInt1Ty(Context), R!=APFloat::cmpLessThan); case FCmpInst::FCMP_OGE: - return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan || + return ConstantInt::get(Type::getInt1Ty(Context), R==APFloat::cmpGreaterThan || R==APFloat::cmpEqual); } } else if (isa<VectorType>(C1->getType())) { SmallVector<Constant*, 16> C1Elts, C2Elts; - C1->getVectorElements(C1Elts); - C2->getVectorElements(C2Elts); - + C1->getVectorElements(Context, C1Elts); + C2->getVectorElements(Context, C2Elts); + // If we can constant fold the comparison of each element, constant fold // the whole vector comparison. SmallVector<Constant*, 4> ResElts; - const Type *InEltTy = C1Elts[0]->getType(); - bool isFP = InEltTy->isFloatingPoint(); - const Type *ResEltTy = InEltTy; - if (isFP) - ResEltTy = IntegerType::get(InEltTy->getPrimitiveSizeInBits()); - for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) { // Compare the elements, producing an i1 result or constant expr. - Constant *C; - if (isFP) - C = ConstantExpr::getFCmp(pred, C1Elts[i], C2Elts[i]); - else - C = ConstantExpr::getICmp(pred, C1Elts[i], C2Elts[i]); - - // If it is a bool or undef result, convert to the dest type. - if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) { - if (CI->isZero()) - ResElts.push_back(Constant::getNullValue(ResEltTy)); - else - ResElts.push_back(Constant::getAllOnesValue(ResEltTy)); - } else if (isa<UndefValue>(C)) { - ResElts.push_back(UndefValue::get(ResEltTy)); - } else { - break; - } + ResElts.push_back( + ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i])); } - - if (ResElts.size() == C1Elts.size()) - return ConstantVector::get(&ResElts[0], ResElts.size()); + return ConstantVector::get(&ResElts[0], ResElts.size()); } if (C1->getType()->isFloatingPoint()) { int Result = -1; // -1 = unknown, 0 = known false, 1 = known true. - switch (evaluateFCmpRelation(C1, C2)) { - default: assert(0 && "Unknown relation!"); + switch (evaluateFCmpRelation(Context, C1, C2)) { + default: llvm_unreachable("Unknown relation!"); case FCmpInst::FCMP_UNO: case FCmpInst::FCMP_ORD: case FCmpInst::FCMP_UEQ: @@ -1459,110 +1580,115 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, Result = 1; break; } - + // If we evaluated the result, return it now. - if (Result != -1) { - if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) { - if (Result == 0) - return Constant::getNullValue(VectorType::getInteger(VT)); - else - return Constant::getAllOnesValue(VectorType::getInteger(VT)); - } - return ConstantInt::get(Type::Int1Ty, Result); - } - + if (Result != -1) + return ConstantInt::get(Type::getInt1Ty(Context), Result); + } else { // Evaluate the relation between the two constants, per the predicate. int Result = -1; // -1 = unknown, 0 = known false, 1 = known true. - switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) { - default: assert(0 && "Unknown relational!"); + switch (evaluateICmpRelation(Context, C1, C2, CmpInst::isSigned(pred))) { + default: llvm_unreachable("Unknown relational!"); case ICmpInst::BAD_ICMP_PREDICATE: break; // Couldn't determine anything about these constants. case ICmpInst::ICMP_EQ: // We know the constants are equal! // If we know the constants are equal, we can decide the result of this // computation precisely. - Result = (pred == ICmpInst::ICMP_EQ || - pred == ICmpInst::ICMP_ULE || - pred == ICmpInst::ICMP_SLE || - pred == ICmpInst::ICMP_UGE || - pred == ICmpInst::ICMP_SGE); + Result = ICmpInst::isTrueWhenEqual((ICmpInst::Predicate)pred); break; case ICmpInst::ICMP_ULT: - // If we know that C1 < C2, we can decide the result of this computation - // precisely. - Result = (pred == ICmpInst::ICMP_ULT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_ULE); + switch (pred) { + case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_ULE: + Result = 1; break; + case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_UGE: + Result = 0; break; + } break; case ICmpInst::ICMP_SLT: - // If we know that C1 < C2, we can decide the result of this computation - // precisely. - Result = (pred == ICmpInst::ICMP_SLT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_SLE); + switch (pred) { + case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_SLE: + Result = 1; break; + case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_SGE: + Result = 0; break; + } break; case ICmpInst::ICMP_UGT: - // If we know that C1 > C2, we can decide the result of this computation - // precisely. - Result = (pred == ICmpInst::ICMP_UGT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_UGE); + switch (pred) { + case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGE: + Result = 1; break; + case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_ULE: + Result = 0; break; + } break; case ICmpInst::ICMP_SGT: - // If we know that C1 > C2, we can decide the result of this computation - // precisely. - Result = (pred == ICmpInst::ICMP_SGT || - pred == ICmpInst::ICMP_NE || - pred == ICmpInst::ICMP_SGE); + switch (pred) { + case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_NE: case ICmpInst::ICMP_SGE: + Result = 1; break; + case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_SLE: + Result = 0; break; + } break; case ICmpInst::ICMP_ULE: - // If we know that C1 <= C2, we can only partially decide this relation. if (pred == ICmpInst::ICMP_UGT) Result = 0; - if (pred == ICmpInst::ICMP_ULT) Result = 1; + if (pred == ICmpInst::ICMP_ULT || pred == ICmpInst::ICMP_ULE) Result = 1; break; case ICmpInst::ICMP_SLE: - // If we know that C1 <= C2, we can only partially decide this relation. if (pred == ICmpInst::ICMP_SGT) Result = 0; - if (pred == ICmpInst::ICMP_SLT) Result = 1; + if (pred == ICmpInst::ICMP_SLT || pred == ICmpInst::ICMP_SLE) Result = 1; break; - case ICmpInst::ICMP_UGE: - // If we know that C1 >= C2, we can only partially decide this relation. if (pred == ICmpInst::ICMP_ULT) Result = 0; - if (pred == ICmpInst::ICMP_UGT) Result = 1; + if (pred == ICmpInst::ICMP_UGT || pred == ICmpInst::ICMP_UGE) Result = 1; break; case ICmpInst::ICMP_SGE: - // If we know that C1 >= C2, we can only partially decide this relation. if (pred == ICmpInst::ICMP_SLT) Result = 0; - if (pred == ICmpInst::ICMP_SGT) Result = 1; + if (pred == ICmpInst::ICMP_SGT || pred == ICmpInst::ICMP_SGE) Result = 1; break; - case ICmpInst::ICMP_NE: - // If we know that C1 != C2, we can only partially decide this relation. if (pred == ICmpInst::ICMP_EQ) Result = 0; if (pred == ICmpInst::ICMP_NE) Result = 1; break; } - + // If we evaluated the result, return it now. - if (Result != -1) { - if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) { - if (Result == 0) - return Constant::getNullValue(VT); - else - return Constant::getAllOnesValue(VT); + if (Result != -1) + return ConstantInt::get(Type::getInt1Ty(Context), Result); + + // If the right hand side is a bitcast, try using its inverse to simplify + // it by moving it to the left hand side. + if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(C2)) { + if (CE2->getOpcode() == Instruction::BitCast) { + Constant *CE2Op0 = CE2->getOperand(0); + Constant *Inverse = ConstantExpr::getBitCast(C1, CE2Op0->getType()); + return ConstantExpr::getICmp(pred, Inverse, CE2Op0); } - return ConstantInt::get(Type::Int1Ty, Result); } - + + // If the left hand side is an extension, try eliminating it. + if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { + if (CE1->getOpcode() == Instruction::SExt || + CE1->getOpcode() == Instruction::ZExt) { + Constant *CE1Op0 = CE1->getOperand(0); + Constant *CE1Inverse = ConstantExpr::getTrunc(CE1, CE1Op0->getType()); + if (CE1Inverse == CE1Op0) { + // Check whether we can safely truncate the right hand side. + Constant *C2Inverse = ConstantExpr::getTrunc(C2, CE1Op0->getType()); + if (ConstantExpr::getZExt(C2Inverse, C2->getType()) == C2) { + return ConstantExpr::getICmp(pred, CE1Inverse, C2Inverse); + } + } + } + } + if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) { - // If C2 is a constant expr and C1 isn't, flop them around and fold the + // If C2 is a constant expr and C1 isn't, flip them around and fold the // other way if possible. switch (pred) { case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_NE: // No change of predicate required. - return ConstantFoldCompareInstruction(pred, C2, C1); + return ConstantFoldCompareInstruction(Context, pred, C2, C1); case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_SLT: @@ -1574,7 +1700,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, case ICmpInst::ICMP_SGE: // Change the predicate as necessary to swap the operands. pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred); - return ConstantFoldCompareInstruction(pred, C2, C1); + return ConstantFoldCompareInstruction(Context, pred, C2, C1); default: // These predicates cannot be flopped around. break; @@ -1584,12 +1710,33 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, return 0; } -Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, +/// isInBoundsIndices - Test whether the given sequence of *normalized* indices +/// is "inbounds". +static bool isInBoundsIndices(Constant *const *Idxs, size_t NumIdx) { + // No indices means nothing that could be out of bounds. + if (NumIdx == 0) return true; + + // If the first index is zero, it's in bounds. + if (Idxs[0]->isNullValue()) return true; + + // If the first index is one and all the rest are zero, it's in bounds, + // by the one-past-the-end rule. + if (!cast<ConstantInt>(Idxs[0])->isOne()) + return false; + for (unsigned i = 1, e = NumIdx; i != e; ++i) + if (!Idxs[i]->isNullValue()) + return false; + return true; +} + +Constant *llvm::ConstantFoldGetElementPtr(LLVMContext &Context, + Constant *C, + bool inBounds, Constant* const *Idxs, unsigned NumIdx) { if (NumIdx == 0 || (NumIdx == 1 && Idxs[0]->isNullValue())) - return const_cast<Constant*>(C); + return C; if (isa<UndefValue>(C)) { const PointerType *Ptr = cast<PointerType>(C->getType()); @@ -1614,12 +1761,12 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, (Value**)Idxs, (Value**)Idxs+NumIdx); assert(Ty != 0 && "Invalid indices for GEP!"); - return - ConstantPointerNull::get(PointerType::get(Ty,Ptr->getAddressSpace())); + return ConstantPointerNull::get( + PointerType::get(Ty,Ptr->getAddressSpace())); } } - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) { + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { // Combine Indices - If the source pointer to this getelementptr instruction // is a getelementptr instruction, combine the indices of the two // getelementptr instructions into a single instruction. @@ -1643,9 +1790,10 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, if (!Idx0->isNullValue()) { const Type *IdxTy = Combined->getType(); if (IdxTy != Idx0->getType()) { - Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Type::Int64Ty); + Constant *C1 = + ConstantExpr::getSExtOrBitCast(Idx0, Type::getInt64Ty(Context)); Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, - Type::Int64Ty); + Type::getInt64Ty(Context)); Combined = ConstantExpr::get(Instruction::Add, C1, C2); } else { Combined = @@ -1655,8 +1803,13 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, NewIndices.push_back(Combined); NewIndices.insert(NewIndices.end(), Idxs+1, Idxs+NumIdx); - return ConstantExpr::getGetElementPtr(CE->getOperand(0), &NewIndices[0], - NewIndices.size()); + return (inBounds && cast<GEPOperator>(CE)->isInBounds()) ? + ConstantExpr::getInBoundsGetElementPtr(CE->getOperand(0), + &NewIndices[0], + NewIndices.size()) : + ConstantExpr::getGetElementPtr(CE->getOperand(0), + &NewIndices[0], + NewIndices.size()); } } @@ -1672,19 +1825,23 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, if (const ArrayType *CAT = dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType())) if (CAT->getElementType() == SAT->getElementType()) - return ConstantExpr::getGetElementPtr( + return inBounds ? + ConstantExpr::getInBoundsGetElementPtr( + (Constant*)CE->getOperand(0), Idxs, NumIdx) : + ConstantExpr::getGetElementPtr( (Constant*)CE->getOperand(0), Idxs, NumIdx); } - + // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1) // Into: inttoptr (i64 0 to i8*) // This happens with pointers to member functions in C++. if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 && isa<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) && - cast<PointerType>(CE->getType())->getElementType() == Type::Int8Ty) { + cast<PointerType>(CE->getType())->getElementType() == + Type::getInt8Ty(Context)) { Constant *Base = CE->getOperand(0); Constant *Offset = Idxs[0]; - + // Convert the smaller integer to the larger type. if (Offset->getType()->getPrimitiveSizeInBits() < Base->getType()->getPrimitiveSizeInBits()) @@ -1692,11 +1849,74 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, else if (Base->getType()->getPrimitiveSizeInBits() < Offset->getType()->getPrimitiveSizeInBits()) Base = ConstantExpr::getZExt(Base, Offset->getType()); - + Base = ConstantExpr::getAdd(Base, Offset); return ConstantExpr::getIntToPtr(Base, CE->getType()); } } + + // Check to see if any array indices are not within the corresponding + // notional array bounds. If so, try to determine if they can be factored + // out into preceding dimensions. + bool Unknown = false; + SmallVector<Constant *, 8> NewIdxs; + const Type *Ty = C->getType(); + const Type *Prev = 0; + for (unsigned i = 0; i != NumIdx; + Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) { + if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) + if (ATy->getNumElements() <= INT64_MAX && + ATy->getNumElements() != 0 && + CI->getSExtValue() >= (int64_t)ATy->getNumElements()) { + if (isa<SequentialType>(Prev)) { + // It's out of range, but we can factor it into the prior + // dimension. + NewIdxs.resize(NumIdx); + ConstantInt *Factor = ConstantInt::get(CI->getType(), + ATy->getNumElements()); + NewIdxs[i] = ConstantExpr::getSRem(CI, Factor); + + Constant *PrevIdx = Idxs[i-1]; + Constant *Div = ConstantExpr::getSDiv(CI, Factor); + + // Before adding, extend both operands to i64 to avoid + // overflow trouble. + if (PrevIdx->getType() != Type::getInt64Ty(Context)) + PrevIdx = ConstantExpr::getSExt(PrevIdx, + Type::getInt64Ty(Context)); + if (Div->getType() != Type::getInt64Ty(Context)) + Div = ConstantExpr::getSExt(Div, + Type::getInt64Ty(Context)); + + NewIdxs[i-1] = ConstantExpr::getAdd(PrevIdx, Div); + } else { + // It's out of range, but the prior dimension is a struct + // so we can't do anything about it. + Unknown = true; + } + } + } else { + // We don't know if it's in range or not. + Unknown = true; + } + } + + // If we did any factoring, start over with the adjusted indices. + if (!NewIdxs.empty()) { + for (unsigned i = 0; i != NumIdx; ++i) + if (!NewIdxs[i]) NewIdxs[i] = Idxs[i]; + return inBounds ? + ConstantExpr::getInBoundsGetElementPtr(C, NewIdxs.data(), + NewIdxs.size()) : + ConstantExpr::getGetElementPtr(C, NewIdxs.data(), NewIdxs.size()); + } + + // If all indices are known integers and normalized, we can do a simple + // check for the "inbounds" property. + if (!Unknown && !inBounds && + isa<GlobalVariable>(C) && isInBoundsIndices(Idxs, NumIdx)) + return ConstantExpr::getInBoundsGetElementPtr(C, Idxs, NumIdx); + return 0; } - diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index 49aea11870af..cc97001e3cf3 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -23,37 +23,46 @@ namespace llvm { class Value; class Constant; class Type; + class LLVMContext; // Constant fold various types of instruction... Constant *ConstantFoldCastInstruction( + LLVMContext &Context, unsigned opcode, ///< The opcode of the cast - const Constant *V, ///< The source constant + Constant *V, ///< The source constant const Type *DestTy ///< The destination type ); - Constant *ConstantFoldSelectInstruction(const Constant *Cond, - const Constant *V1, - const Constant *V2); - Constant *ConstantFoldExtractElementInstruction(const Constant *Val, - const Constant *Idx); - Constant *ConstantFoldInsertElementInstruction(const Constant *Val, - const Constant *Elt, - const Constant *Idx); - Constant *ConstantFoldShuffleVectorInstruction(const Constant *V1, - const Constant *V2, - const Constant *Mask); - Constant *ConstantFoldExtractValueInstruction(const Constant *Agg, + Constant *ConstantFoldSelectInstruction(LLVMContext &Context, + Constant *Cond, + Constant *V1, Constant *V2); + Constant *ConstantFoldExtractElementInstruction(LLVMContext &Context, + Constant *Val, + Constant *Idx); + Constant *ConstantFoldInsertElementInstruction(LLVMContext &Context, + Constant *Val, + Constant *Elt, + Constant *Idx); + Constant *ConstantFoldShuffleVectorInstruction(LLVMContext &Context, + Constant *V1, + Constant *V2, + Constant *Mask); + Constant *ConstantFoldExtractValueInstruction(LLVMContext &Context, + Constant *Agg, const unsigned *Idxs, unsigned NumIdx); - Constant *ConstantFoldInsertValueInstruction(const Constant *Agg, - const Constant *Val, - const unsigned* Idxs, + Constant *ConstantFoldInsertValueInstruction(LLVMContext &Context, + Constant *Agg, + Constant *Val, + const unsigned *Idxs, unsigned NumIdx); - Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, - const Constant *V2); - Constant *ConstantFoldCompareInstruction(unsigned short predicate, - const Constant *C1, - const Constant *C2); - Constant *ConstantFoldGetElementPtr(const Constant *C, + Constant *ConstantFoldBinaryInstruction(LLVMContext &Context, + unsigned Opcode, Constant *V1, + Constant *V2); + Constant *ConstantFoldCompareInstruction(LLVMContext &Context, + unsigned short predicate, + Constant *C1, Constant *C2); + Constant *ConstantFoldGetElementPtr(LLVMContext &Context, Constant *C, + bool inBounds, Constant* const *Idxs, unsigned NumIdx); } // End llvm namespace diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index a9e4e78ee1f4..529c45557bc1 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -12,19 +12,23 @@ //===----------------------------------------------------------------------===// #include "llvm/Constants.h" +#include "LLVMContextImpl.h" #include "ConstantFold.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalValue.h" #include "llvm/Instructions.h" -#include "llvm/MDNode.h" #include "llvm/Module.h" +#include "llvm/Operator.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/System/Mutex.h" #include "llvm/System/RWMutex.h" #include "llvm/System/Threading.h" @@ -38,8 +42,64 @@ using namespace llvm; // Constant Class //===----------------------------------------------------------------------===// -// Becomes a no-op when multithreading is disabled. -ManagedStatic<sys::SmartRWMutex<true> > ConstantsLock; +// Constructor to create a '0' constant of arbitrary type... +static const uint64_t zero[2] = {0, 0}; +Constant* Constant::getNullValue(const Type* Ty) { + switch (Ty->getTypeID()) { + case Type::IntegerTyID: + return ConstantInt::get(Ty, 0); + case Type::FloatTyID: + return ConstantFP::get(Ty->getContext(), APFloat(APInt(32, 0))); + case Type::DoubleTyID: + return ConstantFP::get(Ty->getContext(), APFloat(APInt(64, 0))); + case Type::X86_FP80TyID: + return ConstantFP::get(Ty->getContext(), APFloat(APInt(80, 2, zero))); + case Type::FP128TyID: + return ConstantFP::get(Ty->getContext(), + APFloat(APInt(128, 2, zero), true)); + case Type::PPC_FP128TyID: + return ConstantFP::get(Ty->getContext(), APFloat(APInt(128, 2, zero))); + case Type::PointerTyID: + return ConstantPointerNull::get(cast<PointerType>(Ty)); + case Type::StructTyID: + case Type::ArrayTyID: + case Type::VectorTyID: + return ConstantAggregateZero::get(Ty); + default: + // Function, Label, or Opaque type? + assert(!"Cannot create a null constant of that type!"); + return 0; + } +} + +Constant* Constant::getIntegerValue(const Type* Ty, const APInt &V) { + const Type *ScalarTy = Ty->getScalarType(); + + // Create the base integer constant. + Constant *C = ConstantInt::get(Ty->getContext(), V); + + // Convert an integer to a pointer, if necessary. + if (const PointerType *PTy = dyn_cast<PointerType>(ScalarTy)) + C = ConstantExpr::getIntToPtr(C, PTy); + + // Broadcast a scalar to a vector, if necessary. + if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) + C = ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C)); + + return C; +} + +Constant* Constant::getAllOnesValue(const Type* Ty) { + if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty)) + return ConstantInt::get(Ty->getContext(), + APInt::getAllOnesValue(ITy->getBitWidth())); + + std::vector<Constant*> Elts; + const VectorType* VTy = cast<VectorType>(Ty); + Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType())); + assert(Elts[0] && "Not a vector integer type!"); + return cast<ConstantVector>(ConstantVector::get(Elts)); +} void Constant::destroyConstantImpl() { // When a Constant is destroyed, there may be lingering @@ -52,10 +112,11 @@ void Constant::destroyConstantImpl() { while (!use_empty()) { Value *V = use_back(); #ifndef NDEBUG // Only in -g mode... - if (!isa<Constant>(V)) - DOUT << "While deleting: " << *this - << "\n\nUse still stuck around after Def is destroyed: " - << *V << "\n\n"; + if (!isa<Constant>(V)) { + errs() << "While deleting: " << *this + << "\n\nUse still stuck around after Def is destroyed: " + << *V << "\n\n"; + } #endif assert(isa<Constant>(V) && "References remain to Constant being destroyed"); Constant *CV = cast<Constant>(V); @@ -99,85 +160,33 @@ bool Constant::canTrap() const { } } -/// ContainsRelocations - Return true if the constant value contains relocations -/// which cannot be resolved at compile time. Kind argument is used to filter -/// only 'interesting' sorts of relocations. -bool Constant::ContainsRelocations(unsigned Kind) const { - if (const GlobalValue* GV = dyn_cast<GlobalValue>(this)) { - bool isLocal = GV->hasLocalLinkage(); - if ((Kind & Reloc::Local) && isLocal) { - // Global has local linkage and 'local' kind of relocations are - // requested - return true; - } - - if ((Kind & Reloc::Global) && !isLocal) { - // Global has non-local linkage and 'global' kind of relocations are - // requested - return true; - } - return false; +/// getRelocationInfo - This method classifies the entry according to +/// whether or not it may generate a relocation entry. This must be +/// conservative, so if it might codegen to a relocatable entry, it should say +/// so. The return values are: +/// +/// NoRelocation: This constant pool entry is guaranteed to never have a +/// relocation applied to it (because it holds a simple constant like +/// '4'). +/// LocalRelocation: This entry has relocations, but the entries are +/// guaranteed to be resolvable by the static linker, so the dynamic +/// linker will never see them. +/// GlobalRelocations: This entry may have arbitrary relocations. +/// +/// FIXME: This really should not be in VMCore. +Constant::PossibleRelocationsTy Constant::getRelocationInfo() const { + if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) { + if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) + return LocalRelocation; // Local to this file/library. + return GlobalRelocations; // Global reference. } - + + PossibleRelocationsTy Result = NoRelocation; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (getOperand(i)->ContainsRelocations(Kind)) - return true; - - return false; -} - -// Static constructor to create a '0' constant of arbitrary type... -static const uint64_t zero[2] = {0, 0}; -Constant *Constant::getNullValue(const Type *Ty) { - switch (Ty->getTypeID()) { - case Type::IntegerTyID: - return ConstantInt::get(Ty, 0); - case Type::FloatTyID: - return ConstantFP::get(APFloat(APInt(32, 0))); - case Type::DoubleTyID: - return ConstantFP::get(APFloat(APInt(64, 0))); - case Type::X86_FP80TyID: - return ConstantFP::get(APFloat(APInt(80, 2, zero))); - case Type::FP128TyID: - return ConstantFP::get(APFloat(APInt(128, 2, zero), true)); - case Type::PPC_FP128TyID: - return ConstantFP::get(APFloat(APInt(128, 2, zero))); - case Type::PointerTyID: - return ConstantPointerNull::get(cast<PointerType>(Ty)); - case Type::StructTyID: - case Type::ArrayTyID: - case Type::VectorTyID: - return ConstantAggregateZero::get(Ty); - default: - // Function, Label, or Opaque type? - assert(!"Cannot create a null constant of that type!"); - return 0; - } -} - -Constant *Constant::getAllOnesValue(const Type *Ty) { - if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty)) - return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth())); - return ConstantVector::getAllOnesValue(cast<VectorType>(Ty)); -} - -// Static constructor to create an integral constant with all bits set -ConstantInt *ConstantInt::getAllOnesValue(const Type *Ty) { - if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty)) - return ConstantInt::get(APInt::getAllOnesValue(ITy->getBitWidth())); - return 0; -} - -/// @returns the value for a vector integer constant of the given type that -/// has all its bits set to true. -/// @brief Get the all ones value -ConstantVector *ConstantVector::getAllOnesValue(const VectorType *Ty) { - std::vector<Constant*> Elts; - Elts.resize(Ty->getNumElements(), - ConstantInt::getAllOnesValue(Ty->getElementType())); - assert(Elts[0] && "Not a vector integer type!"); - return cast<ConstantVector>(ConstantVector::get(Elts)); + Result = std::max(Result, getOperand(i)->getRelocationInfo()); + + return Result; } @@ -185,7 +194,8 @@ ConstantVector *ConstantVector::getAllOnesValue(const VectorType *Ty) { /// type, returns the elements of the vector in the specified smallvector. /// This handles breaking down a vector undef into undef elements, etc. For /// constant exprs and other cases we can't handle, we return an empty vector. -void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const { +void Constant::getVectorElements(LLVMContext &Context, + SmallVectorImpl<Constant*> &Elts) const { assert(isa<VectorType>(getType()) && "Not a vector constant!"); if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) { @@ -220,95 +230,45 @@ ConstantInt::ConstantInt(const IntegerType *Ty, const APInt& V) assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type"); } -ConstantInt *ConstantInt::TheTrueVal = 0; -ConstantInt *ConstantInt::TheFalseVal = 0; - -namespace llvm { - void CleanupTrueFalse(void *) { - ConstantInt::ResetTrueFalse(); - } -} - -static ManagedCleanup<llvm::CleanupTrueFalse> TrueFalseCleanup; - -ConstantInt *ConstantInt::CreateTrueFalseVals(bool WhichOne) { - assert(TheTrueVal == 0 && TheFalseVal == 0); - TheTrueVal = get(Type::Int1Ty, 1); - TheFalseVal = get(Type::Int1Ty, 0); - - // Ensure that llvm_shutdown nulls out TheTrueVal/TheFalseVal. - TrueFalseCleanup.Register(); - - return WhichOne ? TheTrueVal : TheFalseVal; +ConstantInt* ConstantInt::getTrue(LLVMContext &Context) { + LLVMContextImpl *pImpl = Context.pImpl; + sys::SmartScopedWriter<true>(pImpl->ConstantsLock); + if (pImpl->TheTrueVal) + return pImpl->TheTrueVal; + else + return (pImpl->TheTrueVal = + ConstantInt::get(IntegerType::get(Context, 1), 1)); } - -namespace { - struct DenseMapAPIntKeyInfo { - struct KeyTy { - APInt val; - const Type* type; - KeyTy(const APInt& V, const Type* Ty) : val(V), type(Ty) {} - KeyTy(const KeyTy& that) : val(that.val), type(that.type) {} - bool operator==(const KeyTy& that) const { - return type == that.type && this->val == that.val; - } - bool operator!=(const KeyTy& that) const { - return !this->operator==(that); - } - }; - static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); } - static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); } - static unsigned getHashValue(const KeyTy &Key) { - return DenseMapInfo<void*>::getHashValue(Key.type) ^ - Key.val.getHashValue(); - } - static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { - return LHS == RHS; - } - static bool isPod() { return false; } - }; +ConstantInt* ConstantInt::getFalse(LLVMContext &Context) { + LLVMContextImpl *pImpl = Context.pImpl; + sys::SmartScopedWriter<true>(pImpl->ConstantsLock); + if (pImpl->TheFalseVal) + return pImpl->TheFalseVal; + else + return (pImpl->TheFalseVal = + ConstantInt::get(IntegerType::get(Context, 1), 0)); } -typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, - DenseMapAPIntKeyInfo> IntMapTy; -static ManagedStatic<IntMapTy> IntConstants; - -ConstantInt *ConstantInt::get(const IntegerType *Ty, - uint64_t V, bool isSigned) { - return get(APInt(Ty->getBitWidth(), V, isSigned)); -} - -Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) { - Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned); - - // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) - return - ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C)); - - return C; -} - // Get a ConstantInt from an APInt. Note that the value stored in the DenseMap // as the key, is a DenseMapAPIntKeyInfo::KeyTy which has provided the // operator== and operator!= to ensure that the DenseMap doesn't attempt to // compare APInt's of different widths, which would violate an APInt class // invariant which generates an assertion. -ConstantInt *ConstantInt::get(const APInt& V) { +ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt& V) { // Get the corresponding integer type for the bit width of the value. - const IntegerType *ITy = IntegerType::get(V.getBitWidth()); + const IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); // get an existing value or the insertion position DenseMapAPIntKeyInfo::KeyTy Key(V, ITy); - ConstantsLock->reader_acquire(); - ConstantInt *&Slot = (*IntConstants)[Key]; - ConstantsLock->reader_release(); + Context.pImpl->ConstantsLock.reader_acquire(); + ConstantInt *&Slot = Context.pImpl->IntConstants[Key]; + Context.pImpl->ConstantsLock.reader_release(); if (!Slot) { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - ConstantInt *&NewSlot = (*IntConstants)[Key]; + sys::SmartScopedWriter<true> Writer(Context.pImpl->ConstantsLock); + ConstantInt *&NewSlot = Context.pImpl->IntConstants[Key]; if (!Slot) { NewSlot = new ConstantInt(ITy, V); } @@ -319,117 +279,153 @@ ConstantInt *ConstantInt::get(const APInt& V) { } } -Constant *ConstantInt::get(const Type *Ty, const APInt &V) { - ConstantInt *C = ConstantInt::get(V); +Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) { + Constant *C = get(cast<IntegerType>(Ty->getScalarType()), + V, isSigned); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) + return ConstantVector::get( + std::vector<Constant *>(VTy->getNumElements(), C)); + + return C; +} + +ConstantInt* ConstantInt::get(const IntegerType* Ty, uint64_t V, + bool isSigned) { + return get(Ty->getContext(), APInt(Ty->getBitWidth(), V, isSigned)); +} + +ConstantInt* ConstantInt::getSigned(const IntegerType* Ty, int64_t V) { + return get(Ty, V, true); +} + +Constant *ConstantInt::getSigned(const Type *Ty, int64_t V) { + return get(Ty, V, true); +} + +Constant* ConstantInt::get(const Type* Ty, const APInt& V) { + ConstantInt *C = get(Ty->getContext(), V); assert(C->getType() == Ty->getScalarType() && "ConstantInt type doesn't match the type implied by its value!"); // For vectors, broadcast the value. if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) - return - ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C)); + return ConstantVector::get( + std::vector<Constant *>(VTy->getNumElements(), C)); return C; } +ConstantInt* ConstantInt::get(const IntegerType* Ty, const StringRef& Str, + uint8_t radix) { + return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix)); +} + //===----------------------------------------------------------------------===// // ConstantFP //===----------------------------------------------------------------------===// static const fltSemantics *TypeToFloatSemantics(const Type *Ty) { - if (Ty == Type::FloatTy) + if (Ty->isFloatTy()) return &APFloat::IEEEsingle; - if (Ty == Type::DoubleTy) + if (Ty->isDoubleTy()) return &APFloat::IEEEdouble; - if (Ty == Type::X86_FP80Ty) + if (Ty->isX86_FP80Ty()) return &APFloat::x87DoubleExtended; - else if (Ty == Type::FP128Ty) + else if (Ty->isFP128Ty()) return &APFloat::IEEEquad; - assert(Ty == Type::PPC_FP128Ty && "Unknown FP format"); + assert(Ty->isPPC_FP128Ty() && "Unknown FP format"); return &APFloat::PPCDoubleDouble; } -ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) - : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { - assert(&V.getSemantics() == TypeToFloatSemantics(Ty) && - "FP type Mismatch"); +/// get() - This returns a constant fp for the specified value in the +/// specified type. This should only be used for simple constant values like +/// 2.0/1.0 etc, that are known-valid both as double and as the target format. +Constant* ConstantFP::get(const Type* Ty, double V) { + LLVMContext &Context = Ty->getContext(); + + APFloat FV(V); + bool ignored; + FV.convert(*TypeToFloatSemantics(Ty->getScalarType()), + APFloat::rmNearestTiesToEven, &ignored); + Constant *C = get(Context, FV); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) + return ConstantVector::get( + std::vector<Constant *>(VTy->getNumElements(), C)); + + return C; } -bool ConstantFP::isNullValue() const { - return Val.isZero() && !Val.isNegative(); + +Constant* ConstantFP::get(const Type* Ty, const StringRef& Str) { + LLVMContext &Context = Ty->getContext(); + + APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str); + Constant *C = get(Context, FV); + + // For vectors, broadcast the value. + if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) + return ConstantVector::get( + std::vector<Constant *>(VTy->getNumElements(), C)); + + return C; } -ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) { + +ConstantFP* ConstantFP::getNegativeZero(const Type* Ty) { + LLVMContext &Context = Ty->getContext(); APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF(); apf.changeSign(); - return ConstantFP::get(apf); + return get(Context, apf); } -bool ConstantFP::isExactlyValue(const APFloat& V) const { - return Val.bitwiseIsEqual(V); -} -namespace { - struct DenseMapAPFloatKeyInfo { - struct KeyTy { - APFloat val; - KeyTy(const APFloat& V) : val(V){} - KeyTy(const KeyTy& that) : val(that.val) {} - bool operator==(const KeyTy& that) const { - return this->val.bitwiseIsEqual(that.val); - } - bool operator!=(const KeyTy& that) const { - return !this->operator==(that); - } - }; - static inline KeyTy getEmptyKey() { - return KeyTy(APFloat(APFloat::Bogus,1)); - } - static inline KeyTy getTombstoneKey() { - return KeyTy(APFloat(APFloat::Bogus,2)); - } - static unsigned getHashValue(const KeyTy &Key) { - return Key.val.getHashValue(); - } - static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { - return LHS == RHS; +Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) { + if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) + if (PTy->getElementType()->isFloatingPoint()) { + std::vector<Constant*> zeros(PTy->getNumElements(), + getNegativeZero(PTy->getElementType())); + return ConstantVector::get(PTy, zeros); } - static bool isPod() { return false; } - }; -} -//---- ConstantFP::get() implementation... -// -typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, - DenseMapAPFloatKeyInfo> FPMapTy; + if (Ty->isFloatingPoint()) + return getNegativeZero(Ty); + + return Constant::getNullValue(Ty); +} -static ManagedStatic<FPMapTy> FPConstants; -ConstantFP *ConstantFP::get(const APFloat &V) { +// ConstantFP accessors. +ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { DenseMapAPFloatKeyInfo::KeyTy Key(V); - ConstantsLock->reader_acquire(); - ConstantFP *&Slot = (*FPConstants)[Key]; - ConstantsLock->reader_release(); + LLVMContextImpl* pImpl = Context.pImpl; + + pImpl->ConstantsLock.reader_acquire(); + ConstantFP *&Slot = pImpl->FPConstants[Key]; + pImpl->ConstantsLock.reader_release(); if (!Slot) { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - ConstantFP *&NewSlot = (*FPConstants)[Key]; + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + ConstantFP *&NewSlot = pImpl->FPConstants[Key]; if (!NewSlot) { const Type *Ty; if (&V.getSemantics() == &APFloat::IEEEsingle) - Ty = Type::FloatTy; + Ty = Type::getFloatTy(Context); else if (&V.getSemantics() == &APFloat::IEEEdouble) - Ty = Type::DoubleTy; + Ty = Type::getDoubleTy(Context); else if (&V.getSemantics() == &APFloat::x87DoubleExtended) - Ty = Type::X86_FP80Ty; + Ty = Type::getX86_FP80Ty(Context); else if (&V.getSemantics() == &APFloat::IEEEquad) - Ty = Type::FP128Ty; + Ty = Type::getFP128Ty(Context); else { assert(&V.getSemantics() == &APFloat::PPCDoubleDouble && "Unknown FP format"); - Ty = Type::PPC_FP128Ty; + Ty = Type::getPPC_FP128Ty(Context); } NewSlot = new ConstantFP(Ty, V); } @@ -440,22 +436,24 @@ ConstantFP *ConstantFP::get(const APFloat &V) { return Slot; } -/// get() - This returns a constant fp for the specified value in the -/// specified type. This should only be used for simple constant values like -/// 2.0/1.0 etc, that are known-valid both as double and as the target format. -Constant *ConstantFP::get(const Type *Ty, double V) { - APFloat FV(V); - bool ignored; - FV.convert(*TypeToFloatSemantics(Ty->getScalarType()), - APFloat::rmNearestTiesToEven, &ignored); - Constant *C = get(FV); +ConstantFP *ConstantFP::getInfinity(const Type *Ty, bool Negative) { + const fltSemantics &Semantics = *TypeToFloatSemantics(Ty); + return ConstantFP::get(Ty->getContext(), + APFloat::getInf(Semantics, Negative)); +} - // For vectors, broadcast the value. - if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) - return - ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C)); +ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) + : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { + assert(&V.getSemantics() == TypeToFloatSemantics(Ty) && + "FP type Mismatch"); +} - return C; +bool ConstantFP::isNullValue() const { + return Val.isZero() && !Val.isNegative(); +} + +bool ConstantFP::isExactlyValue(const APFloat& V) const { + return Val.bitwiseIsEqual(V); } //===----------------------------------------------------------------------===// @@ -474,14 +472,65 @@ ConstantArray::ConstantArray(const ArrayType *T, for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { Constant *C = *I; - assert((C->getType() == T->getElementType() || - (T->isAbstract() && - C->getType()->getTypeID() == T->getElementType()->getTypeID())) && + assert(C->getType() == T->getElementType() && "Initializer for array element doesn't match array element type!"); *OL = C; } } +Constant *ConstantArray::get(const ArrayType *Ty, + const std::vector<Constant*> &V) { + for (unsigned i = 0, e = V.size(); i != e; ++i) { + assert(V[i]->getType() == Ty->getElementType() && + "Wrong type in array element initializer"); + } + LLVMContextImpl *pImpl = Ty->getContext().pImpl; + // If this is an all-zero array, return a ConstantAggregateZero object + if (!V.empty()) { + Constant *C = V[0]; + if (!C->isNullValue()) { + // Implicitly locked. + return pImpl->ArrayConstants.getOrCreate(Ty, V); + } + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) { + // Implicitly locked. + return pImpl->ArrayConstants.getOrCreate(Ty, V); + } + } + + return ConstantAggregateZero::get(Ty); +} + + +Constant* ConstantArray::get(const ArrayType* T, Constant* const* Vals, + unsigned NumVals) { + // FIXME: make this the primary ctor method. + return get(T, std::vector<Constant*>(Vals, Vals+NumVals)); +} + +/// ConstantArray::get(const string&) - Return an array that is initialized to +/// contain the specified string. If length is zero then a null terminator is +/// added to the specified string so that it may be used in a natural way. +/// Otherwise, the length parameter specifies how much of the string to use +/// and it won't be null terminated. +/// +Constant* ConstantArray::get(LLVMContext &Context, const StringRef &Str, + bool AddNull) { + std::vector<Constant*> ElementVals; + for (unsigned i = 0; i < Str.size(); ++i) + ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i])); + + // Add a null terminator to the string... + if (AddNull) { + ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0)); + } + + ArrayType *ATy = ArrayType::get(Type::getInt8Ty(Context), ElementVals.size()); + return get(ATy, ElementVals); +} + + ConstantStruct::ConstantStruct(const StructType *T, const std::vector<Constant*> &V) @@ -494,16 +543,41 @@ ConstantStruct::ConstantStruct(const StructType *T, for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { Constant *C = *I; - assert((C->getType() == T->getElementType(I-V.begin()) || - ((T->getElementType(I-V.begin())->isAbstract() || - C->getType()->isAbstract()) && - T->getElementType(I-V.begin())->getTypeID() == - C->getType()->getTypeID())) && + assert(C->getType() == T->getElementType(I-V.begin()) && "Initializer for struct element doesn't match struct element type!"); *OL = C; } } +// ConstantStruct accessors. +Constant* ConstantStruct::get(const StructType* T, + const std::vector<Constant*>& V) { + LLVMContextImpl* pImpl = T->getContext().pImpl; + + // Create a ConstantAggregateZero value if all elements are zeros... + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (!V[i]->isNullValue()) + // Implicitly locked. + return pImpl->StructConstants.getOrCreate(T, V); + + return ConstantAggregateZero::get(T); +} + +Constant* ConstantStruct::get(LLVMContext &Context, + const std::vector<Constant*>& V, bool packed) { + std::vector<const Type*> StructEls; + StructEls.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) + StructEls.push_back(V[i]->getType()); + return get(StructType::get(Context, StructEls, packed), V); +} + +Constant* ConstantStruct::get(LLVMContext &Context, + Constant* const *Vals, unsigned NumVals, + bool Packed) { + // FIXME: make this the primary ctor method. + return get(Context, std::vector<Constant*>(Vals, Vals+NumVals), Packed); +} ConstantVector::ConstantVector(const VectorType *T, const std::vector<Constant*> &V) @@ -514,297 +588,66 @@ ConstantVector::ConstantVector(const VectorType *T, for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end(); I != E; ++I, ++OL) { Constant *C = *I; - assert((C->getType() == T->getElementType() || - (T->isAbstract() && - C->getType()->getTypeID() == T->getElementType()->getTypeID())) && + assert(C->getType() == T->getElementType() && "Initializer for vector element doesn't match vector element type!"); *OL = C; } } +// ConstantVector accessors. +Constant* ConstantVector::get(const VectorType* T, + const std::vector<Constant*>& V) { + assert(!V.empty() && "Vectors can't be empty"); + LLVMContext &Context = T->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + // If this is an all-undef or alll-zero vector, return a + // ConstantAggregateZero or UndefValue. + Constant *C = V[0]; + bool isZero = C->isNullValue(); + bool isUndef = isa<UndefValue>(C); -namespace llvm { -// We declare several classes private to this file, so use an anonymous -// namespace -namespace { - -/// UnaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement unary constant exprs. -class VISIBILITY_HIDDEN UnaryConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly one operand - void *operator new(size_t s) { - return User::operator new(s, 1); - } - UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) - : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { - Op<0>() = C; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// BinaryConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement binary constant exprs. -class VISIBILITY_HIDDEN BinaryConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly two operands - void *operator new(size_t s) { - return User::operator new(s, 2); - } - BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) - : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { - Op<0>() = C1; - Op<1>() = C2; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// SelectConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement select constant exprs. -class VISIBILITY_HIDDEN SelectConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } - SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { - Op<0>() = C1; - Op<1>() = C2; - Op<2>() = C3; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// ExtractElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// extractelement constant exprs. -class VISIBILITY_HIDDEN ExtractElementConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly two operands - void *operator new(size_t s) { - return User::operator new(s, 2); - } - ExtractElementConstantExpr(Constant *C1, Constant *C2) - : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), - Instruction::ExtractElement, &Op<0>(), 2) { - Op<0>() = C1; - Op<1>() = C2; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// InsertElementConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// insertelement constant exprs. -class VISIBILITY_HIDDEN InsertElementConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } - InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(C1->getType(), Instruction::InsertElement, - &Op<0>(), 3) { - Op<0>() = C1; - Op<1>() = C2; - Op<2>() = C3; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// ShuffleVectorConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// shufflevector constant exprs. -class VISIBILITY_HIDDEN ShuffleVectorConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(VectorType::get( - cast<VectorType>(C1->getType())->getElementType(), - cast<VectorType>(C3->getType())->getNumElements()), - Instruction::ShuffleVector, - &Op<0>(), 3) { - Op<0>() = C1; - Op<1>() = C2; - Op<2>() = C3; - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// ExtractValueConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// extractvalue constant exprs. -class VISIBILITY_HIDDEN ExtractValueConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly one operand - void *operator new(size_t s) { - return User::operator new(s, 1); - } - ExtractValueConstantExpr(Constant *Agg, - const SmallVector<unsigned, 4> &IdxList, - const Type *DestTy) - : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), - Indices(IdxList) { - Op<0>() = Agg; - } - - /// Indices - These identify which value to extract. - const SmallVector<unsigned, 4> Indices; - - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -/// InsertValueConstantExpr - This class is private to -/// Constants.cpp, and is used behind the scenes to implement -/// insertvalue constant exprs. -class VISIBILITY_HIDDEN InsertValueConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -public: - // allocate space for exactly one operand - void *operator new(size_t s) { - return User::operator new(s, 2); - } - InsertValueConstantExpr(Constant *Agg, Constant *Val, - const SmallVector<unsigned, 4> &IdxList, - const Type *DestTy) - : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), - Indices(IdxList) { - Op<0>() = Agg; - Op<1>() = Val; - } - - /// Indices - These identify the position for the insertion. - const SmallVector<unsigned, 4> Indices; - - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - - -/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is -/// used behind the scenes to implement getelementpr constant exprs. -class VISIBILITY_HIDDEN GetElementPtrConstantExpr : public ConstantExpr { - GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList, - const Type *DestTy); -public: - static GetElementPtrConstantExpr *Create(Constant *C, - const std::vector<Constant*>&IdxList, - const Type *DestTy) { - return new(IdxList.size() + 1) - GetElementPtrConstantExpr(C, IdxList, DestTy); - } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -// CompareConstantExpr - This class is private to Constants.cpp, and is used -// behind the scenes to implement ICmp and FCmp constant expressions. This is -// needed in order to store the predicate value for these instructions. -struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT - // allocate space for exactly two operands - void *operator new(size_t s) { - return User::operator new(s, 2); - } - unsigned short predicate; - CompareConstantExpr(const Type *ty, Instruction::OtherOps opc, - unsigned short pred, Constant* LHS, Constant* RHS) - : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { - Op<0>() = LHS; - Op<1>() = RHS; + if (isZero || isUndef) { + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) { + isZero = isUndef = false; + break; + } } - /// Transparently provide more efficient getOperand methods. - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -}; - -} // end anonymous namespace - -template <> -struct OperandTraits<UnaryConstantExpr> : FixedNumOperandTraits<1> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) - -template <> -struct OperandTraits<BinaryConstantExpr> : FixedNumOperandTraits<2> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) - -template <> -struct OperandTraits<SelectConstantExpr> : FixedNumOperandTraits<3> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) - -template <> -struct OperandTraits<ExtractElementConstantExpr> : FixedNumOperandTraits<2> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) - -template <> -struct OperandTraits<InsertElementConstantExpr> : FixedNumOperandTraits<3> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) - -template <> -struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) - -template <> -struct OperandTraits<ExtractValueConstantExpr> : FixedNumOperandTraits<1> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) - -template <> -struct OperandTraits<InsertValueConstantExpr> : FixedNumOperandTraits<2> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) - -template <> -struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> { -}; - -GetElementPtrConstantExpr::GetElementPtrConstantExpr - (Constant *C, - const std::vector<Constant*> &IdxList, - const Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - OperandTraits<GetElementPtrConstantExpr>::op_end(this) - - (IdxList.size()+1), - IdxList.size()+1) { - OperandList[0] = C; - for (unsigned i = 0, E = IdxList.size(); i != E; ++i) - OperandList[i+1] = IdxList[i]; + + if (isZero) + return ConstantAggregateZero::get(T); + if (isUndef) + return UndefValue::get(T); + + // Implicitly locked. + return pImpl->VectorConstants.getOrCreate(T, V); } -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) - +Constant* ConstantVector::get(const std::vector<Constant*>& V) { + assert(!V.empty() && "Cannot infer type if V is empty"); + return get(VectorType::get(V.front()->getType(),V.size()), V); +} -template <> -struct OperandTraits<CompareConstantExpr> : FixedNumOperandTraits<2> { -}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) +Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) { + // FIXME: make this the primary ctor method. + return get(std::vector<Constant*>(Vals, Vals+NumVals)); +} +Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::Add, C1, C2, + OverflowingBinaryOperator::NoSignedWrap); +} -} // End llvm namespace +Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::Sub, C1, C2, + OverflowingBinaryOperator::NoSignedWrap); +} +Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::SDiv, C1, C2, + SDivOperator::IsExact); +} // Utility function for determining if a ConstantExpr is a CastOp or not. This // can't be inline because we don't want to #include Instruction.h into @@ -814,8 +657,32 @@ bool ConstantExpr::isCast() const { } bool ConstantExpr::isCompare() const { - return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp || - getOpcode() == Instruction::VICmp || getOpcode() == Instruction::VFCmp; + return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp; +} + +bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const { + if (getOpcode() != Instruction::GetElementPtr) return false; + + gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this); + User::const_op_iterator OI = next(this->op_begin()); + + // Skip the first index, as it has no static limit. + ++GEPI; + ++OI; + + // The remaining indices must be compile-time known integers within the + // bounds of the corresponding notional static array types. + for (; GEPI != E; ++GEPI, ++OI) { + ConstantInt *CI = dyn_cast<ConstantInt>(*OI); + if (!CI) return false; + if (const ArrayType *ATy = dyn_cast<ArrayType>(*GEPI)) + if (CI->getValue().getActiveBits() > 64 || + CI->getZExtValue() >= ATy->getNumElements()) + return false; + } + + // All the indices checked out. + return true; } bool ConstantExpr::hasIndices() const { @@ -831,93 +698,11 @@ const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const { return cast<InsertValueConstantExpr>(this)->Indices; } -/// ConstantExpr::get* - Return some common constants without having to -/// specify the full Instruction::OPCODE identifier. -/// -Constant *ConstantExpr::getNeg(Constant *C) { - // API compatibility: Adjust integer opcodes to floating-point opcodes. - if (C->getType()->isFPOrFPVector()) - return getFNeg(C); - assert(C->getType()->isIntOrIntVector() && - "Cannot NEG a nonintegral value!"); - return get(Instruction::Sub, - ConstantExpr::getZeroValueForNegationExpr(C->getType()), - C); -} -Constant *ConstantExpr::getFNeg(Constant *C) { - assert(C->getType()->isFPOrFPVector() && - "Cannot FNEG a non-floating-point value!"); - return get(Instruction::FSub, - ConstantExpr::getZeroValueForNegationExpr(C->getType()), - C); -} -Constant *ConstantExpr::getNot(Constant *C) { - assert(C->getType()->isIntOrIntVector() && - "Cannot NOT a nonintegral value!"); - return get(Instruction::Xor, C, - Constant::getAllOnesValue(C->getType())); -} -Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) { - return get(Instruction::Add, C1, C2); -} -Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) { - return get(Instruction::FAdd, C1, C2); -} -Constant *ConstantExpr::getSub(Constant *C1, Constant *C2) { - return get(Instruction::Sub, C1, C2); -} -Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) { - return get(Instruction::FSub, C1, C2); -} -Constant *ConstantExpr::getMul(Constant *C1, Constant *C2) { - return get(Instruction::Mul, C1, C2); -} -Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) { - return get(Instruction::FMul, C1, C2); -} -Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2) { - return get(Instruction::UDiv, C1, C2); -} -Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2) { - return get(Instruction::SDiv, C1, C2); -} -Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { - return get(Instruction::FDiv, C1, C2); -} -Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) { - return get(Instruction::URem, C1, C2); -} -Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) { - return get(Instruction::SRem, C1, C2); -} -Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) { - return get(Instruction::FRem, C1, C2); -} -Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) { - return get(Instruction::And, C1, C2); -} -Constant *ConstantExpr::getOr(Constant *C1, Constant *C2) { - return get(Instruction::Or, C1, C2); -} -Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) { - return get(Instruction::Xor, C1, C2); -} unsigned ConstantExpr::getPredicate() const { assert(getOpcode() == Instruction::FCmp || - getOpcode() == Instruction::ICmp || - getOpcode() == Instruction::VFCmp || - getOpcode() == Instruction::VICmp); + getOpcode() == Instruction::ICmp); return ((const CompareConstantExpr*)this)->predicate; } -Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) { - return get(Instruction::Shl, C1, C2); -} -Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2) { - return get(Instruction::LShr, C1, C2); -} -Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) { - return get(Instruction::AShr, C1, C2); -} /// getWithOperandReplaced - Return a constant expression identical to this /// one, but with the specified operand set to the specified value. @@ -969,15 +754,19 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { for (unsigned i = 1, e = getNumOperands(); i != e; ++i) Ops[i-1] = getOperand(i); if (OpNo == 0) - return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) : + ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); Ops[OpNo-1] = Op; - return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) : + ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); } default: assert(getNumOperands() == 2 && "Must be binary operator?"); Op0 = (OpNo == 0) ? Op : getOperand(0); Op1 = (OpNo == 1) ? Op : getOperand(1); - return ConstantExpr::get(getOpcode(), Op0, Op1); + return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData); } } @@ -1019,15 +808,15 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); case Instruction::GetElementPtr: - return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) : + ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1); case Instruction::ICmp: case Instruction::FCmp: - case Instruction::VICmp: - case Instruction::VFCmp: return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); default: assert(getNumOperands() == 2 && "Must be binary operator?"); - return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]); + return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData); } } @@ -1037,7 +826,7 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay - if (Ty == Type::Int1Ty) + if (Ty == Type::getInt1Ty(Ty->getContext())) return Val == 0 || Val == 1; if (NumBits >= 64) return true; // always true, has to fit in largest type @@ -1047,7 +836,7 @@ bool ConstantInt::isValueValidForType(const Type *Ty, uint64_t Val) { bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) { unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth(); // assert okay - if (Ty == Type::Int1Ty) + if (Ty == Type::getInt1Ty(Ty->getContext())) return Val == 0 || Val == 1 || Val == -1; if (NumBits >= 64) return true; // always true, has to fit in largest type @@ -1096,404 +885,36 @@ bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) { //===----------------------------------------------------------------------===// // Factory Function Implementation - -// The number of operands for each ConstantCreator::create method is -// determined by the ConstantTraits template. -// ConstantCreator - A class that is used to create constants by -// ValueMap*. This class should be partially specialized if there is -// something strange that needs to be done to interface to the ctor for the -// constant. -// -namespace llvm { - template<class ValType> - struct ConstantTraits; - - template<typename T, typename Alloc> - struct VISIBILITY_HIDDEN ConstantTraits< std::vector<T, Alloc> > { - static unsigned uses(const std::vector<T, Alloc>& v) { - return v.size(); - } - }; - - template<class ConstantClass, class TypeClass, class ValType> - struct VISIBILITY_HIDDEN ConstantCreator { - static ConstantClass *create(const TypeClass *Ty, const ValType &V) { - return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V); - } - }; - - template<class ConstantClass, class TypeClass> - struct VISIBILITY_HIDDEN ConvertConstantType { - static void convert(ConstantClass *OldC, const TypeClass *NewTy) { - assert(0 && "This type cannot be converted!\n"); - abort(); - } - }; - - template<class ValType, class TypeClass, class ConstantClass, - bool HasLargeKey = false /*true for arrays and structs*/ > - class VISIBILITY_HIDDEN ValueMap : public AbstractTypeUser { - public: - typedef std::pair<const Type*, ValType> MapKey; - typedef std::map<MapKey, Constant *> MapTy; - typedef std::map<Constant*, typename MapTy::iterator> InverseMapTy; - typedef std::map<const Type*, typename MapTy::iterator> AbstractTypeMapTy; - private: - /// Map - This is the main map from the element descriptor to the Constants. - /// This is the primary way we avoid creating two of the same shape - /// constant. - MapTy Map; - - /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping - /// from the constants to their element in Map. This is important for - /// removal of constants from the array, which would otherwise have to scan - /// through the map with very large keys. - InverseMapTy InverseMap; - - /// AbstractTypeMap - Map for abstract type constants. - /// - AbstractTypeMapTy AbstractTypeMap; - - /// ValueMapLock - Mutex for this map. - sys::SmartMutex<true> ValueMapLock; - - public: - // NOTE: This function is not locked. It is the caller's responsibility - // to enforce proper synchronization. - typename MapTy::iterator map_end() { return Map.end(); } - - /// InsertOrGetItem - Return an iterator for the specified element. - /// If the element exists in the map, the returned iterator points to the - /// entry and Exists=true. If not, the iterator points to the newly - /// inserted entry and returns Exists=false. Newly inserted entries have - /// I->second == 0, and should be filled in. - /// NOTE: This function is not locked. It is the caller's responsibility - // to enforce proper synchronization. - typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, Constant *> - &InsertVal, - bool &Exists) { - std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal); - Exists = !IP.second; - return IP.first; - } - -private: - typename MapTy::iterator FindExistingElement(ConstantClass *CP) { - if (HasLargeKey) { - typename InverseMapTy::iterator IMI = InverseMap.find(CP); - assert(IMI != InverseMap.end() && IMI->second != Map.end() && - IMI->second->second == CP && - "InverseMap corrupt!"); - return IMI->second; - } - - typename MapTy::iterator I = - Map.find(MapKey(static_cast<const TypeClass*>(CP->getRawType()), - getValType(CP))); - if (I == Map.end() || I->second != CP) { - // FIXME: This should not use a linear scan. If this gets to be a - // performance problem, someone should look at this. - for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) - /* empty */; - } - return I; - } - - ConstantClass* Create(const TypeClass *Ty, const ValType &V, - typename MapTy::iterator I) { - ConstantClass* Result = - ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); - - assert(Result->getType() == Ty && "Type specified is not correct!"); - I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); - - if (HasLargeKey) // Remember the reverse mapping if needed. - InverseMap.insert(std::make_pair(Result, I)); - - // If the type of the constant is abstract, make sure that an entry - // exists for it in the AbstractTypeMap. - if (Ty->isAbstract()) { - typename AbstractTypeMapTy::iterator TI = - AbstractTypeMap.find(Ty); - - if (TI == AbstractTypeMap.end()) { - // Add ourselves to the ATU list of the type. - cast<DerivedType>(Ty)->addAbstractTypeUser(this); - - AbstractTypeMap.insert(TI, std::make_pair(Ty, I)); - } - } - - return Result; - } -public: - - /// getOrCreate - Return the specified constant from the map, creating it if - /// necessary. - ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { - sys::SmartScopedLock<true> Lock(&ValueMapLock); - MapKey Lookup(Ty, V); - ConstantClass* Result = 0; - - typename MapTy::iterator I = Map.find(Lookup); - // Is it in the map? - if (I != Map.end()) - Result = static_cast<ConstantClass *>(I->second); - - if (!Result) { - // If no preexisting value, create one now... - Result = Create(Ty, V, I); - } - - return Result; - } - - void remove(ConstantClass *CP) { - sys::SmartScopedLock<true> Lock(&ValueMapLock); - typename MapTy::iterator I = FindExistingElement(CP); - assert(I != Map.end() && "Constant not found in constant table!"); - assert(I->second == CP && "Didn't find correct element?"); - - if (HasLargeKey) // Remember the reverse mapping if needed. - InverseMap.erase(CP); - - // Now that we found the entry, make sure this isn't the entry that - // the AbstractTypeMap points to. - const TypeClass *Ty = static_cast<const TypeClass *>(I->first.first); - if (Ty->isAbstract()) { - assert(AbstractTypeMap.count(Ty) && - "Abstract type not in AbstractTypeMap?"); - typename MapTy::iterator &ATMEntryIt = AbstractTypeMap[Ty]; - if (ATMEntryIt == I) { - // Yes, we are removing the representative entry for this type. - // See if there are any other entries of the same type. - typename MapTy::iterator TmpIt = ATMEntryIt; - - // First check the entry before this one... - if (TmpIt != Map.begin()) { - --TmpIt; - if (TmpIt->first.first != Ty) // Not the same type, move back... - ++TmpIt; - } - - // If we didn't find the same type, try to move forward... - if (TmpIt == ATMEntryIt) { - ++TmpIt; - if (TmpIt == Map.end() || TmpIt->first.first != Ty) - --TmpIt; // No entry afterwards with the same type - } - - // If there is another entry in the map of the same abstract type, - // update the AbstractTypeMap entry now. - if (TmpIt != ATMEntryIt) { - ATMEntryIt = TmpIt; - } else { - // Otherwise, we are removing the last instance of this type - // from the table. Remove from the ATM, and from user list. - cast<DerivedType>(Ty)->removeAbstractTypeUser(this); - AbstractTypeMap.erase(Ty); - } - } - } - - Map.erase(I); - } - - - /// MoveConstantToNewSlot - If we are about to change C to be the element - /// specified by I, update our internal data structures to reflect this - /// fact. - /// NOTE: This function is not locked. It is the responsibility of the - /// caller to enforce proper synchronization if using this method. - void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { - // First, remove the old location of the specified constant in the map. - typename MapTy::iterator OldI = FindExistingElement(C); - assert(OldI != Map.end() && "Constant not found in constant table!"); - assert(OldI->second == C && "Didn't find correct element?"); - - // If this constant is the representative element for its abstract type, - // update the AbstractTypeMap so that the representative element is I. - if (C->getType()->isAbstract()) { - typename AbstractTypeMapTy::iterator ATI = - AbstractTypeMap.find(C->getType()); - assert(ATI != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - if (ATI->second == OldI) - ATI->second = I; - } - - // Remove the old entry from the map. - Map.erase(OldI); - - // Update the inverse map so that we know that this constant is now - // located at descriptor I. - if (HasLargeKey) { - assert(I->second == C && "Bad inversemap entry!"); - InverseMap[C] = I; - } - } - - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - sys::SmartScopedLock<true> Lock(&ValueMapLock); - typename AbstractTypeMapTy::iterator I = - AbstractTypeMap.find(cast<Type>(OldTy)); - - assert(I != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - - // Convert a constant at a time until the last one is gone. The last one - // leaving will remove() itself, causing the AbstractTypeMapEntry to be - // eliminated eventually. - do { - ConvertConstantType<ConstantClass, - TypeClass>::convert( - static_cast<ConstantClass *>(I->second->second), - cast<TypeClass>(NewTy)); - - I = AbstractTypeMap.find(cast<Type>(OldTy)); - } while (I != AbstractTypeMap.end()); - } - - // If the type became concrete without being refined to any other existing - // type, we just remove ourselves from the ATU list. - void typeBecameConcrete(const DerivedType *AbsTy) { - AbsTy->removeAbstractTypeUser(this); - } - - void dump() const { - DOUT << "Constant.cpp: ValueMap\n"; - } - }; -} - - - -//---- ConstantAggregateZero::get() implementation... -// -namespace llvm { - // ConstantAggregateZero does not take extra "value" argument... - template<class ValType> - struct ConstantCreator<ConstantAggregateZero, Type, ValType> { - static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ - return new ConstantAggregateZero(Ty); - } - }; - - template<> - struct ConvertConstantType<ConstantAggregateZero, Type> { - static void convert(ConstantAggregateZero *OldC, const Type *NewTy) { - // Make everyone now use a constant of the new type... - Constant *New = ConstantAggregateZero::get(NewTy); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -static ManagedStatic<ValueMap<char, Type, - ConstantAggregateZero> > AggZeroConstants; - -static char getValType(ConstantAggregateZero *CPZ) { return 0; } - -ConstantAggregateZero *ConstantAggregateZero::get(const Type *Ty) { +ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) && "Cannot create an aggregate zero of non-aggregate type!"); + LLVMContextImpl *pImpl = Ty->getContext().pImpl; // Implicitly locked. - return AggZeroConstants->getOrCreate(Ty, 0); + return pImpl->AggZeroConstants.getOrCreate(Ty, 0); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantAggregateZero::destroyConstant() { // Implicitly locked. - AggZeroConstants->remove(this); + getType()->getContext().pImpl->AggZeroConstants.remove(this); destroyConstantImpl(); } -//---- ConstantArray::get() implementation... -// -namespace llvm { - template<> - struct ConvertConstantType<ConstantArray, ArrayType> { - static void convert(ConstantArray *OldC, const ArrayType *NewTy) { - // Make everyone now use a constant of the new type... - std::vector<Constant*> C; - for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) - C.push_back(cast<Constant>(OldC->getOperand(i))); - Constant *New = ConstantArray::get(NewTy, C); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -static std::vector<Constant*> getValType(ConstantArray *CA) { - std::vector<Constant*> Elements; - Elements.reserve(CA->getNumOperands()); - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - Elements.push_back(cast<Constant>(CA->getOperand(i))); - return Elements; -} - -typedef ValueMap<std::vector<Constant*>, ArrayType, - ConstantArray, true /*largekey*/> ArrayConstantsTy; -static ManagedStatic<ArrayConstantsTy> ArrayConstants; - -Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector<Constant*> &V) { - // If this is an all-zero array, return a ConstantAggregateZero object - if (!V.empty()) { - Constant *C = V[0]; - if (!C->isNullValue()) { - // Implicitly locked. - return ArrayConstants->getOrCreate(Ty, V); - } - for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - // Implicitly locked. - return ArrayConstants->getOrCreate(Ty, V); - } - } - - return ConstantAggregateZero::get(Ty); -} - /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { // Implicitly locked. - ArrayConstants->remove(this); + getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } -/// ConstantArray::get(const string&) - Return an array that is initialized to -/// contain the specified string. If length is zero then a null terminator is -/// added to the specified string so that it may be used in a natural way. -/// Otherwise, the length parameter specifies how much of the string to use -/// and it won't be null terminated. -/// -Constant *ConstantArray::get(const std::string &Str, bool AddNull) { - std::vector<Constant*> ElementVals; - for (unsigned i = 0; i < Str.length(); ++i) - ElementVals.push_back(ConstantInt::get(Type::Int8Ty, Str[i])); - - // Add a null terminator to the string... - if (AddNull) { - ElementVals.push_back(ConstantInt::get(Type::Int8Ty, 0)); - } - - ArrayType *ATy = ArrayType::get(Type::Int8Ty, ElementVals.size()); - return ConstantArray::get(ATy, ElementVals); -} - /// isString - This method returns true if the array is an array of i8, and /// if the elements of the array are all ConstantInt's. bool ConstantArray::isString() const { // Check the element type for i8... - if (getType()->getElementType() != Type::Int8Ty) + if (getType()->getElementType() != Type::getInt8Ty(getContext())) return false; // Check the elements to make sure they are all integers, not constant // expressions. @@ -1508,17 +929,17 @@ bool ConstantArray::isString() const { /// null bytes except its terminator. bool ConstantArray::isCString() const { // Check the element type for i8... - if (getType()->getElementType() != Type::Int8Ty) + if (getType()->getElementType() != Type::getInt8Ty(getContext())) return false; - Constant *Zero = Constant::getNullValue(getOperand(0)->getType()); + // Last element must be a null. - if (getOperand(getNumOperands()-1) != Zero) + if (!getOperand(getNumOperands()-1)->isNullValue()) return false; // Other elements must be non-null integers. for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) { if (!isa<ConstantInt>(getOperand(i))) return false; - if (getOperand(i) == Zero) + if (getOperand(i)->isNullValue()) return false; } return true; @@ -1543,126 +964,22 @@ std::string ConstantArray::getAsString() const { // namespace llvm { - template<> - struct ConvertConstantType<ConstantStruct, StructType> { - static void convert(ConstantStruct *OldC, const StructType *NewTy) { - // Make everyone now use a constant of the new type... - std::vector<Constant*> C; - for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) - C.push_back(cast<Constant>(OldC->getOperand(i))); - Constant *New = ConstantStruct::get(NewTy, C); - assert(New != OldC && "Didn't replace constant??"); - - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -typedef ValueMap<std::vector<Constant*>, StructType, - ConstantStruct, true /*largekey*/> StructConstantsTy; -static ManagedStatic<StructConstantsTy> StructConstants; - -static std::vector<Constant*> getValType(ConstantStruct *CS) { - std::vector<Constant*> Elements; - Elements.reserve(CS->getNumOperands()); - for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) - Elements.push_back(cast<Constant>(CS->getOperand(i))); - return Elements; -} - -Constant *ConstantStruct::get(const StructType *Ty, - const std::vector<Constant*> &V) { - // Create a ConstantAggregateZero value if all elements are zeros... - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (!V[i]->isNullValue()) - // Implicitly locked. - return StructConstants->getOrCreate(Ty, V); - return ConstantAggregateZero::get(Ty); -} - -Constant *ConstantStruct::get(const std::vector<Constant*> &V, bool packed) { - std::vector<const Type*> StructEls; - StructEls.reserve(V.size()); - for (unsigned i = 0, e = V.size(); i != e; ++i) - StructEls.push_back(V[i]->getType()); - return get(StructType::get(StructEls, packed), V); } // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { // Implicitly locked. - StructConstants->remove(this); + getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } -//---- ConstantVector::get() implementation... -// -namespace llvm { - template<> - struct ConvertConstantType<ConstantVector, VectorType> { - static void convert(ConstantVector *OldC, const VectorType *NewTy) { - // Make everyone now use a constant of the new type... - std::vector<Constant*> C; - for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) - C.push_back(cast<Constant>(OldC->getOperand(i))); - Constant *New = ConstantVector::get(NewTy, C); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -static std::vector<Constant*> getValType(ConstantVector *CP) { - std::vector<Constant*> Elements; - Elements.reserve(CP->getNumOperands()); - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) - Elements.push_back(CP->getOperand(i)); - return Elements; -} - -static ManagedStatic<ValueMap<std::vector<Constant*>, VectorType, - ConstantVector> > VectorConstants; - -Constant *ConstantVector::get(const VectorType *Ty, - const std::vector<Constant*> &V) { - assert(!V.empty() && "Vectors can't be empty"); - // If this is an all-undef or alll-zero vector, return a - // ConstantAggregateZero or UndefValue. - Constant *C = V[0]; - bool isZero = C->isNullValue(); - bool isUndef = isa<UndefValue>(C); - - if (isZero || isUndef) { - for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - isZero = isUndef = false; - break; - } - } - - if (isZero) - return ConstantAggregateZero::get(Ty); - if (isUndef) - return UndefValue::get(Ty); - - // Implicitly locked. - return VectorConstants->getOrCreate(Ty, V); -} - -Constant *ConstantVector::get(const std::vector<Constant*> &V) { - assert(!V.empty() && "Cannot infer type if V is empty"); - return get(VectorType::get(V.front()->getType(),V.size()), V); -} - // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { // Implicitly locked. - VectorConstants->remove(this); + getType()->getContext().pImpl->VectorConstants.remove(this); destroyConstantImpl(); } @@ -1696,45 +1013,16 @@ Constant *ConstantVector::getSplatValue() { //---- ConstantPointerNull::get() implementation... // -namespace llvm { - // ConstantPointerNull does not take extra "value" argument... - template<class ValType> - struct ConstantCreator<ConstantPointerNull, PointerType, ValType> { - static ConstantPointerNull *create(const PointerType *Ty, const ValType &V){ - return new ConstantPointerNull(Ty); - } - }; - - template<> - struct ConvertConstantType<ConstantPointerNull, PointerType> { - static void convert(ConstantPointerNull *OldC, const PointerType *NewTy) { - // Make everyone now use a constant of the new type... - Constant *New = ConstantPointerNull::get(NewTy); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -static ManagedStatic<ValueMap<char, PointerType, - ConstantPointerNull> > NullPtrConstants; - -static char getValType(ConstantPointerNull *) { - return 0; -} - - ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { // Implicitly locked. - return NullPtrConstants->getOrCreate(Ty, 0); + return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0); } // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { // Implicitly locked. - NullPtrConstants->remove(this); + getType()->getContext().pImpl->NullPtrConstants.remove(this); destroyConstantImpl(); } @@ -1742,295 +1030,39 @@ void ConstantPointerNull::destroyConstant() { //---- UndefValue::get() implementation... // -namespace llvm { - // UndefValue does not take extra "value" argument... - template<class ValType> - struct ConstantCreator<UndefValue, Type, ValType> { - static UndefValue *create(const Type *Ty, const ValType &V) { - return new UndefValue(Ty); - } - }; - - template<> - struct ConvertConstantType<UndefValue, Type> { - static void convert(UndefValue *OldC, const Type *NewTy) { - // Make everyone now use a constant of the new type. - Constant *New = UndefValue::get(NewTy); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} - -static ManagedStatic<ValueMap<char, Type, UndefValue> > UndefValueConstants; - -static char getValType(UndefValue *) { - return 0; -} - - UndefValue *UndefValue::get(const Type *Ty) { // Implicitly locked. - return UndefValueConstants->getOrCreate(Ty, 0); + return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0); } // destroyConstant - Remove the constant from the constant table. // void UndefValue::destroyConstant() { // Implicitly locked. - UndefValueConstants->remove(this); - destroyConstantImpl(); -} - -//---- MDString::get() implementation -// - -MDString::MDString(const char *begin, const char *end) - : Constant(Type::MetadataTy, MDStringVal, 0, 0), - StrBegin(begin), StrEnd(end) {} - -static ManagedStatic<StringMap<MDString*> > MDStringCache; - -MDString *MDString::get(const char *StrBegin, const char *StrEnd) { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - StringMapEntry<MDString *> &Entry = MDStringCache->GetOrCreateValue( - StrBegin, StrEnd); - MDString *&S = Entry.getValue(); - if (!S) S = new MDString(Entry.getKeyData(), - Entry.getKeyData() + Entry.getKeyLength()); - - return S; -} - -MDString *MDString::get(const std::string &Str) { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - StringMapEntry<MDString *> &Entry = MDStringCache->GetOrCreateValue( - Str.data(), Str.data() + Str.size()); - MDString *&S = Entry.getValue(); - if (!S) S = new MDString(Entry.getKeyData(), - Entry.getKeyData() + Entry.getKeyLength()); - - return S; -} - -void MDString::destroyConstant() { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - MDStringCache->erase(MDStringCache->find(StrBegin, StrEnd)); - destroyConstantImpl(); -} - -//---- MDNode::get() implementation -// - -static ManagedStatic<FoldingSet<MDNode> > MDNodeSet; - -MDNode::MDNode(Value*const* Vals, unsigned NumVals) - : Constant(Type::MetadataTy, MDNodeVal, 0, 0) { - for (unsigned i = 0; i != NumVals; ++i) - Node.push_back(ElementVH(Vals[i], this)); -} - -void MDNode::Profile(FoldingSetNodeID &ID) const { - for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I) - ID.AddPointer(*I); -} - -MDNode *MDNode::get(Value*const* Vals, unsigned NumVals) { - FoldingSetNodeID ID; - for (unsigned i = 0; i != NumVals; ++i) - ID.AddPointer(Vals[i]); - - ConstantsLock->reader_acquire(); - void *InsertPoint; - MDNode *N = MDNodeSet->FindNodeOrInsertPos(ID, InsertPoint); - ConstantsLock->reader_release(); - - if (!N) { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - N = MDNodeSet->FindNodeOrInsertPos(ID, InsertPoint); - if (!N) { - // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = new(0) MDNode(Vals, NumVals); - MDNodeSet->InsertNode(N, InsertPoint); - } - } - return N; -} - -void MDNode::destroyConstant() { - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); - MDNodeSet->RemoveNode(this); - + getType()->getContext().pImpl->UndefValueConstants.remove(this); destroyConstantImpl(); } //---- ConstantExpr::get() implementations... // -namespace { - -struct ExprMapKeyType { - typedef SmallVector<unsigned, 4> IndexList; - - ExprMapKeyType(unsigned opc, - const std::vector<Constant*> &ops, - unsigned short pred = 0, - const IndexList &inds = IndexList()) - : opcode(opc), predicate(pred), operands(ops), indices(inds) {} - uint16_t opcode; - uint16_t predicate; - std::vector<Constant*> operands; - IndexList indices; - bool operator==(const ExprMapKeyType& that) const { - return this->opcode == that.opcode && - this->predicate == that.predicate && - this->operands == that.operands && - this->indices == that.indices; - } - bool operator<(const ExprMapKeyType & that) const { - return this->opcode < that.opcode || - (this->opcode == that.opcode && this->predicate < that.predicate) || - (this->opcode == that.opcode && this->predicate == that.predicate && - this->operands < that.operands) || - (this->opcode == that.opcode && this->predicate == that.predicate && - this->operands == that.operands && this->indices < that.indices); - } - - bool operator!=(const ExprMapKeyType& that) const { - return !(*this == that); - } -}; - -} - -namespace llvm { - template<> - struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { - static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V, - unsigned short pred = 0) { - if (Instruction::isCast(V.opcode)) - return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); - if ((V.opcode >= Instruction::BinaryOpsBegin && - V.opcode < Instruction::BinaryOpsEnd)) - return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]); - if (V.opcode == Instruction::Select) - return new SelectConstantExpr(V.operands[0], V.operands[1], - V.operands[2]); - if (V.opcode == Instruction::ExtractElement) - return new ExtractElementConstantExpr(V.operands[0], V.operands[1]); - if (V.opcode == Instruction::InsertElement) - return new InsertElementConstantExpr(V.operands[0], V.operands[1], - V.operands[2]); - if (V.opcode == Instruction::ShuffleVector) - return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1], - V.operands[2]); - if (V.opcode == Instruction::InsertValue) - return new InsertValueConstantExpr(V.operands[0], V.operands[1], - V.indices, Ty); - if (V.opcode == Instruction::ExtractValue) - return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); - if (V.opcode == Instruction::GetElementPtr) { - std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end()); - return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty); - } - - // The compare instructions are weird. We have to encode the predicate - // value and it is combined with the instruction opcode by multiplying - // the opcode by one hundred. We must decode this to get the predicate. - if (V.opcode == Instruction::ICmp) - return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, - V.operands[0], V.operands[1]); - if (V.opcode == Instruction::FCmp) - return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, - V.operands[0], V.operands[1]); - if (V.opcode == Instruction::VICmp) - return new CompareConstantExpr(Ty, Instruction::VICmp, V.predicate, - V.operands[0], V.operands[1]); - if (V.opcode == Instruction::VFCmp) - return new CompareConstantExpr(Ty, Instruction::VFCmp, V.predicate, - V.operands[0], V.operands[1]); - assert(0 && "Invalid ConstantExpr!"); - return 0; - } - }; - - template<> - struct ConvertConstantType<ConstantExpr, Type> { - static void convert(ConstantExpr *OldC, const Type *NewTy) { - Constant *New; - switch (OldC->getOpcode()) { - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::PtrToInt: - case Instruction::IntToPtr: - case Instruction::BitCast: - New = ConstantExpr::getCast(OldC->getOpcode(), OldC->getOperand(0), - NewTy); - break; - case Instruction::Select: - New = ConstantExpr::getSelectTy(NewTy, OldC->getOperand(0), - OldC->getOperand(1), - OldC->getOperand(2)); - break; - default: - assert(OldC->getOpcode() >= Instruction::BinaryOpsBegin && - OldC->getOpcode() < Instruction::BinaryOpsEnd); - New = ConstantExpr::getTy(NewTy, OldC->getOpcode(), OldC->getOperand(0), - OldC->getOperand(1)); - break; - case Instruction::GetElementPtr: - // Make everyone now use a constant of the new type... - std::vector<Value*> Idx(OldC->op_begin()+1, OldC->op_end()); - New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), - &Idx[0], Idx.size()); - break; - } - - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } - }; -} // end namespace llvm - - -static ExprMapKeyType getValType(ConstantExpr *CE) { - std::vector<Constant*> Operands; - Operands.reserve(CE->getNumOperands()); - for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) - Operands.push_back(cast<Constant>(CE->getOperand(i))); - return ExprMapKeyType(CE->getOpcode(), Operands, - CE->isCompare() ? CE->getPredicate() : 0, - CE->hasIndices() ? - CE->getIndices() : SmallVector<unsigned, 4>()); -} - -static ManagedStatic<ValueMap<ExprMapKeyType, Type, - ConstantExpr> > ExprConstants; - /// This is a utility function to handle folding of casts and lookup of the /// cast in the ExprConstants map. It is used by the various get* methods below. static inline Constant *getFoldedCast( Instruction::CastOps opc, Constant *C, const Type *Ty) { assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!"); // Fold a few common cases - if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty)) + if (Constant *FC = ConstantFoldCastInstruction(Ty->getContext(), opc, C, Ty)) return FC; + LLVMContextImpl *pImpl = Ty->getContext().pImpl; + // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> argVec(1, C); ExprMapKeyType Key(opc, argVec); // Implicitly locked. - return ExprConstants->getOrCreate(Ty, Key); + return pImpl->ExprConstants.getOrCreate(Ty, Key); } Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { @@ -2041,7 +1073,7 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) { switch (opc) { default: - assert(0 && "Invalid cast opcode"); + llvm_unreachable("Invalid cast opcode"); break; case Instruction::Trunc: return getTrunc(C, Ty); case Instruction::ZExt: return getZExt(C, Ty); @@ -2256,27 +1288,9 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { return getFoldedCast(Instruction::BitCast, C, DstTy); } -Constant *ConstantExpr::getAlignOf(const Type *Ty) { - // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1 - const Type *AligningTy = StructType::get(Type::Int8Ty, Ty, NULL); - Constant *NullPtr = getNullValue(AligningTy->getPointerTo()); - Constant *Zero = ConstantInt::get(Type::Int32Ty, 0); - Constant *One = ConstantInt::get(Type::Int32Ty, 1); - Constant *Indices[2] = { Zero, One }; - Constant *GEP = getGetElementPtr(NullPtr, Indices, 2); - return getCast(Instruction::PtrToInt, GEP, Type::Int32Ty); -} - -Constant *ConstantExpr::getSizeOf(const Type *Ty) { - // sizeof is implemented as: (i64) gep (Ty*)null, 1 - Constant *GEPIdx = ConstantInt::get(Type::Int32Ty, 1); - Constant *GEP = - getGetElementPtr(getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1); - return getCast(Instruction::PtrToInt, GEP, Type::Int64Ty); -} - Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, - Constant *C1, Constant *C2) { + Constant *C1, Constant *C2, + unsigned Flags) { // Check the operands for consistency first assert(Opcode >= Instruction::BinaryOpsBegin && Opcode < Instruction::BinaryOpsEnd && @@ -2284,40 +1298,42 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); - if (ReqTy == C1->getType() || ReqTy == Type::Int1Ty) - if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) + if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext())) + if (Constant *FC = ConstantFoldBinaryInstruction(ReqTy->getContext(), + Opcode, C1, C2)) return FC; // Fold a few common cases... std::vector<Constant*> argVec(1, C1); argVec.push_back(C2); - ExprMapKeyType Key(Opcode, argVec); + ExprMapKeyType Key(Opcode, argVec, 0, Flags); + + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getCompareTy(unsigned short predicate, Constant *C1, Constant *C2) { - bool isVectorType = C1->getType()->getTypeID() == Type::VectorTyID; switch (predicate) { - default: assert(0 && "Invalid CmpInst predicate"); + default: llvm_unreachable("Invalid CmpInst predicate"); case CmpInst::FCMP_FALSE: case CmpInst::FCMP_OEQ: case CmpInst::FCMP_OGT: case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLT: case CmpInst::FCMP_OLE: case CmpInst::FCMP_ONE: case CmpInst::FCMP_ORD: case CmpInst::FCMP_UNO: case CmpInst::FCMP_UEQ: case CmpInst::FCMP_UGT: case CmpInst::FCMP_UGE: case CmpInst::FCMP_ULT: case CmpInst::FCMP_ULE: case CmpInst::FCMP_UNE: case CmpInst::FCMP_TRUE: - return isVectorType ? getVFCmp(predicate, C1, C2) - : getFCmp(predicate, C1, C2); + return getFCmp(predicate, C1, C2); + case CmpInst::ICMP_EQ: case CmpInst::ICMP_NE: case CmpInst::ICMP_UGT: case CmpInst::ICMP_UGE: case CmpInst::ICMP_ULT: case CmpInst::ICMP_ULE: case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: case CmpInst::ICMP_SLT: case CmpInst::ICMP_SLE: - return isVectorType ? getVICmp(predicate, C1, C2) - : getICmp(predicate, C1, C2); + return getICmp(predicate, C1, C2); } } -Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { +Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) { // API compatibility: Adjust integer opcodes to floating-point opcodes. if (C1->getType()->isFPOrFPVector()) { if (Opcode == Instruction::Add) Opcode = Instruction::FAdd; @@ -2382,7 +1398,44 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { } #endif - return getTy(C1->getType(), Opcode, C1, C2); + return getTy(C1->getType(), Opcode, C1, C2, Flags); +} + +Constant* ConstantExpr::getSizeOf(const Type* Ty) { + // sizeof is implemented as: (i64) gep (Ty*)null, 1 + // Note that a non-inbounds gep is used, as null isn't within any object. + Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); + Constant *GEP = getGetElementPtr( + Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1); + return getCast(Instruction::PtrToInt, GEP, + Type::getInt64Ty(Ty->getContext())); +} + +Constant* ConstantExpr::getAlignOf(const Type* Ty) { + // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1 + // Note that a non-inbounds gep is used, as null isn't within any object. + const Type *AligningTy = StructType::get(Ty->getContext(), + Type::getInt8Ty(Ty->getContext()), Ty, NULL); + Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); + Constant *Zero = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 0); + Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); + Constant *Indices[2] = { Zero, One }; + Constant *GEP = getGetElementPtr(NullPtr, Indices, 2); + return getCast(Instruction::PtrToInt, GEP, + Type::getInt32Ty(Ty->getContext())); +} + +Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) { + // offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo + // Note that a non-inbounds gep is used, as null isn't within any object. + Constant *GEPIdx[] = { + ConstantInt::get(Type::getInt64Ty(STy->getContext()), 0), + ConstantInt::get(Type::getInt32Ty(STy->getContext()), FieldNo) + }; + Constant *GEP = getGetElementPtr( + Constant::getNullValue(PointerType::getUnqual(STy)), GEPIdx, 2); + return getCast(Instruction::PtrToInt, GEP, + Type::getInt64Ty(STy->getContext())); } Constant *ConstantExpr::getCompare(unsigned short pred, @@ -2396,7 +1449,8 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands"); if (ReqTy == V1->getType()) - if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) + if (Constant *SC = ConstantFoldSelectInstruction( + ReqTy->getContext(), C, V1, V2)) return SC; // Fold common cases std::vector<Constant*> argVec(3, C); @@ -2404,8 +1458,10 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, argVec[2] = V2; ExprMapKeyType Key(Instruction::Select, argVec); + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, @@ -2416,7 +1472,9 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, cast<PointerType>(ReqTy)->getElementType() && "GEP indices invalid!"); - if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx)) + if (Constant *FC = ConstantFoldGetElementPtr( + ReqTy->getContext(), C, /*inBounds=*/false, + (Constant**)Idxs, NumIdx)) return FC; // Fold a few common cases... assert(isa<PointerType>(C->getType()) && @@ -2429,8 +1487,41 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, ArgVec.push_back(cast<Constant>(Idxs[i])); const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec); + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + + // Implicitly locked. + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, + Constant *C, + Value* const *Idxs, + unsigned NumIdx) { + assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, + Idxs+NumIdx) == + cast<PointerType>(ReqTy)->getElementType() && + "GEP indices invalid!"); + + if (Constant *FC = ConstantFoldGetElementPtr( + ReqTy->getContext(), C, /*inBounds=*/true, + (Constant**)Idxs, NumIdx)) + return FC; // Fold a few common cases... + + assert(isa<PointerType>(C->getType()) && + "Non-pointer type for constant GetElementPtr expression"); + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec; + ArgVec.reserve(NumIdx+1); + ArgVec.push_back(C); + for (unsigned i = 0; i != NumIdx; ++i) + ArgVec.push_back(cast<Constant>(Idxs[i])); + const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, + GEPOperator::IsInBounds); + + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, @@ -2443,11 +1534,27 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, return getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); } +Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, + Value* const *Idxs, + unsigned NumIdx) { + // Get the result type of the getelementptr! + const Type *Ty = + GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx); + assert(Ty && "GEP indices invalid!"); + unsigned As = cast<PointerType>(C->getType())->getAddressSpace(); + return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); +} + Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs, unsigned NumIdx) { return getGetElementPtr(C, (Value* const *)Idxs, NumIdx); } +Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, + Constant* const *Idxs, + unsigned NumIdx) { + return getInBoundsGetElementPtr(C, (Value* const *)Idxs, NumIdx); +} Constant * ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) { @@ -2455,7 +1562,8 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) { assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate"); - if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) + if (Constant *FC = ConstantFoldCompareInstruction( + LHS->getContext(), pred, LHS, RHS)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness @@ -2465,8 +1573,11 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) { // Get the key type with both the opcode and predicate const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred); + LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(Type::Int1Ty, Key); + return + pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); } Constant * @@ -2474,7 +1585,8 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { assert(LHS->getType() == RHS->getType()); assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate"); - if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS)) + if (Constant *FC = ConstantFoldCompareInstruction( + LHS->getContext(), pred, LHS, RHS)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness @@ -2484,123 +1596,33 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { // Get the key type with both the opcode and predicate const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred); - // Implicitly locked. - return ExprConstants->getOrCreate(Type::Int1Ty, Key); -} - -Constant * -ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) { - assert(isa<VectorType>(LHS->getType()) && LHS->getType() == RHS->getType() && - "Tried to create vicmp operation on non-vector type!"); - assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE && - pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate"); - - const VectorType *VTy = cast<VectorType>(LHS->getType()); - const Type *EltTy = VTy->getElementType(); - unsigned NumElts = VTy->getNumElements(); - - // See if we can fold the element-wise comparison of the LHS and RHS. - SmallVector<Constant *, 16> LHSElts, RHSElts; - LHS->getVectorElements(LHSElts); - RHS->getVectorElements(RHSElts); - - if (!LHSElts.empty() && !RHSElts.empty()) { - SmallVector<Constant *, 16> Elts; - for (unsigned i = 0; i != NumElts; ++i) { - Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i], - RHSElts[i]); - if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) { - if (FCI->getZExtValue()) - Elts.push_back(ConstantInt::getAllOnesValue(EltTy)); - else - Elts.push_back(ConstantInt::get(EltTy, 0ULL)); - } else if (FC && isa<UndefValue>(FC)) { - Elts.push_back(UndefValue::get(EltTy)); - } else { - break; - } - } - if (Elts.size() == NumElts) - return ConstantVector::get(&Elts[0], Elts.size()); - } - - // Look up the constant in the table first to ensure uniqueness - std::vector<Constant*> ArgVec; - ArgVec.push_back(LHS); - ArgVec.push_back(RHS); - // Get the key type with both the opcode and predicate - const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred); - - // Implicitly locked. - return ExprConstants->getOrCreate(LHS->getType(), Key); -} - -Constant * -ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) { - assert(isa<VectorType>(LHS->getType()) && - "Tried to create vfcmp operation on non-vector type!"); - assert(LHS->getType() == RHS->getType()); - assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid VFCmp Predicate"); - - const VectorType *VTy = cast<VectorType>(LHS->getType()); - unsigned NumElts = VTy->getNumElements(); - const Type *EltTy = VTy->getElementType(); - const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits()); - const Type *ResultTy = VectorType::get(REltTy, NumElts); - - // See if we can fold the element-wise comparison of the LHS and RHS. - SmallVector<Constant *, 16> LHSElts, RHSElts; - LHS->getVectorElements(LHSElts); - RHS->getVectorElements(RHSElts); - - if (!LHSElts.empty() && !RHSElts.empty()) { - SmallVector<Constant *, 16> Elts; - for (unsigned i = 0; i != NumElts; ++i) { - Constant *FC = ConstantFoldCompareInstruction(pred, LHSElts[i], - RHSElts[i]); - if (ConstantInt *FCI = dyn_cast_or_null<ConstantInt>(FC)) { - if (FCI->getZExtValue()) - Elts.push_back(ConstantInt::getAllOnesValue(REltTy)); - else - Elts.push_back(ConstantInt::get(REltTy, 0ULL)); - } else if (FC && isa<UndefValue>(FC)) { - Elts.push_back(UndefValue::get(REltTy)); - } else { - break; - } - } - if (Elts.size() == NumElts) - return ConstantVector::get(&Elts[0], Elts.size()); - } - - // Look up the constant in the table first to ensure uniqueness - std::vector<Constant*> ArgVec; - ArgVec.push_back(LHS); - ArgVec.push_back(RHS); - // Get the key type with both the opcode and predicate - const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred); + LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl; // Implicitly locked. - return ExprConstants->getOrCreate(ResultTy, Key); + return + pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key); } Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, Constant *Idx) { - if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx)) + if (Constant *FC = ConstantFoldExtractElementInstruction( + ReqTy->getContext(), Val, Idx)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec(1, Val); ArgVec.push_back(Idx); const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec); + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { assert(isa<VectorType>(Val->getType()) && "Tried to create extractelement operation on non-vector type!"); - assert(Idx->getType() == Type::Int32Ty && + assert(Idx->getType() == Type::getInt32Ty(Val->getContext()) && "Extractelement index must be i32 type!"); return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(), Val, Idx); @@ -2608,7 +1630,8 @@ Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, Constant *Elt, Constant *Idx) { - if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) + if (Constant *FC = ConstantFoldInsertElementInstruction( + ReqTy->getContext(), Val, Elt, Idx)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec(1, Val); @@ -2616,8 +1639,10 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, ArgVec.push_back(Idx); const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, @@ -2626,14 +1651,15 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, "Tried to create insertelement operation on non-vector type!"); assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType() && "Insertelement types must match!"); - assert(Idx->getType() == Type::Int32Ty && + assert(Idx->getType() == Type::getInt32Ty(Val->getContext()) && "Insertelement index must be i32 type!"); return getInsertElementTy(Val->getType(), Val, Elt, Idx); } Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, Constant *V2, Constant *Mask) { - if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) + if (Constant *FC = ConstantFoldShuffleVectorInstruction( + ReqTy->getContext(), V1, V2, Mask)) return FC; // Fold a few common cases... // Look up the constant in the table first to ensure uniqueness std::vector<Constant*> ArgVec(1, V1); @@ -2641,8 +1667,10 @@ Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, ArgVec.push_back(Mask); const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + // Implicitly locked. - return ExprConstants->getOrCreate(ReqTy, Key); + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, @@ -2666,7 +1694,8 @@ Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg, "insertvalue type invalid!"); assert(Agg->getType()->isFirstClassType() && "Non-first-class type for constant InsertValue expression"); - Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx); + Constant *FC = ConstantFoldInsertValueInstruction( + ReqTy->getContext(), Agg, Val, Idxs, NumIdx); assert(FC && "InsertValue constant expr couldn't be folded!"); return FC; } @@ -2692,7 +1721,8 @@ Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg, "extractvalue indices invalid!"); assert(Agg->getType()->isFirstClassType() && "Non-first-class type for constant extractvalue expression"); - Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx); + Constant *FC = ConstantFoldExtractValueInstruction( + ReqTy->getContext(), Agg, Idxs, NumIdx); assert(FC && "ExtractValue constant expr couldn't be folded!"); return FC; } @@ -2708,25 +1738,109 @@ Constant *ConstantExpr::getExtractValue(Constant *Agg, return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); } -Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) { - if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) - if (PTy->getElementType()->isFloatingPoint()) { - std::vector<Constant*> zeros(PTy->getNumElements(), - ConstantFP::getNegativeZero(PTy->getElementType())); - return ConstantVector::get(PTy, zeros); - } +Constant* ConstantExpr::getNeg(Constant* C) { + // API compatibility: Adjust integer opcodes to floating-point opcodes. + if (C->getType()->isFPOrFPVector()) + return getFNeg(C); + assert(C->getType()->isIntOrIntVector() && + "Cannot NEG a nonintegral value!"); + return get(Instruction::Sub, + ConstantFP::getZeroValueForNegation(C->getType()), + C); +} - if (Ty->isFloatingPoint()) - return ConstantFP::getNegativeZero(Ty); +Constant* ConstantExpr::getFNeg(Constant* C) { + assert(C->getType()->isFPOrFPVector() && + "Cannot FNEG a non-floating-point value!"); + return get(Instruction::FSub, + ConstantFP::getZeroValueForNegation(C->getType()), + C); +} - return Constant::getNullValue(Ty); +Constant* ConstantExpr::getNot(Constant* C) { + assert(C->getType()->isIntOrIntVector() && + "Cannot NOT a nonintegral value!"); + return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType())); +} + +Constant* ConstantExpr::getAdd(Constant* C1, Constant* C2) { + return get(Instruction::Add, C1, C2); +} + +Constant* ConstantExpr::getFAdd(Constant* C1, Constant* C2) { + return get(Instruction::FAdd, C1, C2); +} + +Constant* ConstantExpr::getSub(Constant* C1, Constant* C2) { + return get(Instruction::Sub, C1, C2); +} + +Constant* ConstantExpr::getFSub(Constant* C1, Constant* C2) { + return get(Instruction::FSub, C1, C2); +} + +Constant* ConstantExpr::getMul(Constant* C1, Constant* C2) { + return get(Instruction::Mul, C1, C2); +} + +Constant* ConstantExpr::getFMul(Constant* C1, Constant* C2) { + return get(Instruction::FMul, C1, C2); +} + +Constant* ConstantExpr::getUDiv(Constant* C1, Constant* C2) { + return get(Instruction::UDiv, C1, C2); +} + +Constant* ConstantExpr::getSDiv(Constant* C1, Constant* C2) { + return get(Instruction::SDiv, C1, C2); +} + +Constant* ConstantExpr::getFDiv(Constant* C1, Constant* C2) { + return get(Instruction::FDiv, C1, C2); +} + +Constant* ConstantExpr::getURem(Constant* C1, Constant* C2) { + return get(Instruction::URem, C1, C2); +} + +Constant* ConstantExpr::getSRem(Constant* C1, Constant* C2) { + return get(Instruction::SRem, C1, C2); +} + +Constant* ConstantExpr::getFRem(Constant* C1, Constant* C2) { + return get(Instruction::FRem, C1, C2); +} + +Constant* ConstantExpr::getAnd(Constant* C1, Constant* C2) { + return get(Instruction::And, C1, C2); +} + +Constant* ConstantExpr::getOr(Constant* C1, Constant* C2) { + return get(Instruction::Or, C1, C2); +} + +Constant* ConstantExpr::getXor(Constant* C1, Constant* C2) { + return get(Instruction::Xor, C1, C2); +} + +Constant* ConstantExpr::getShl(Constant* C1, Constant* C2) { + return get(Instruction::Shl, C1, C2); +} + +Constant* ConstantExpr::getLShr(Constant* C1, Constant* C2) { + return get(Instruction::LShr, C1, C2); +} + +Constant* ConstantExpr::getAShr(Constant* C1, Constant* C2) { + return get(Instruction::AShr, C1, C2); } // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { // Implicitly locked. - ExprConstants->remove(this); + LLVMContextImpl *pImpl = getType()->getContext().pImpl; + pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -2747,12 +1861,16 @@ const char *ConstantExpr::getOpcodeName() const { /// single invocation handles all 1000 uses. Handling them one at a time would /// work, but would be really slow because it would have to unique each updated /// array instance. + void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast<Constant>(To); - std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup; + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, ConstantArray*> Lookup; Lookup.first.first = getType(); Lookup.second = this; @@ -2774,7 +1892,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, } } else { isAllZeros = true; - for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { + for (Use *O = OperandList, *E = OperandList+getNumOperands();O != E; ++O) { Constant *Val = cast<Constant>(O->get()); if (Val == From) { Val = ToC; @@ -2790,10 +1908,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this array type already. - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); bool Exists; - ArrayConstantsTy::MapTy::iterator I = - ArrayConstants->InsertOrGetItem(Lookup, Exists); + LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I = + pImpl->ArrayConstants.InsertOrGetItem(Lookup, Exists); if (Exists) { Replacement = I->second; @@ -2802,12 +1920,12 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, // creating a new constant array, inserting it, replaceallusesof'ing the // old with the new, then deleting the old... just update the current one // in place! - ArrayConstants->MoveConstantToNewSlot(this, I); + pImpl->ArrayConstants.MoveConstantToNewSlot(this, I); // Update to the new value. Optimize for the case when we have a single // operand that we're changing, but handle bulk updates efficiently. if (NumUpdated == 1) { - unsigned OperandToUpdate = U-OperandList; + unsigned OperandToUpdate = U - OperandList; assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); setOperand(OperandToUpdate, ToC); @@ -2838,7 +1956,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, unsigned OperandToUpdate = U-OperandList; assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); - std::pair<StructConstantsTy::MapKey, Constant*> Lookup; + std::pair<LLVMContextImpl::StructConstantsTy::MapKey, ConstantStruct*> Lookup; Lookup.first.first = getType(); Lookup.second = this; std::vector<Constant*> &Values = Lookup.first.second; @@ -2849,7 +1967,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, // compute whether this turns into an all-zeros struct. bool isAllZeros = false; if (!ToC->isNullValue()) { - for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) + for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) Values.push_back(cast<Constant>(O->get())); } else { isAllZeros = true; @@ -2861,15 +1979,18 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + Constant *Replacement = 0; if (isAllZeros) { Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this array type already. - sys::SmartScopedWriter<true> Writer(&*ConstantsLock); + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); bool Exists; - StructConstantsTy::MapTy::iterator I = - StructConstants->InsertOrGetItem(Lookup, Exists); + LLVMContextImpl::StructConstantsTy::MapTy::iterator I = + pImpl->StructConstants.InsertOrGetItem(Lookup, Exists); if (Exists) { Replacement = I->second; @@ -2878,7 +1999,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, // creating a new constant struct, inserting it, replaceallusesof'ing the // old with the new, then deleting the old... just update the current one // in place! - StructConstants->MoveConstantToNewSlot(this, I); + pImpl->StructConstants.MoveConstantToNewSlot(this, I); // Update to the new value. setOperand(OperandToUpdate, ToC); @@ -2907,7 +2028,7 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Values.push_back(Val); } - Constant *Replacement = ConstantVector::get(getType(), Values); + Constant *Replacement = get(getType(), Values); assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. @@ -2992,22 +2113,18 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (C2 == From) C2 = To; if (getOpcode() == Instruction::ICmp) Replacement = ConstantExpr::getICmp(getPredicate(), C1, C2); - else if (getOpcode() == Instruction::FCmp) - Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2); - else if (getOpcode() == Instruction::VICmp) - Replacement = ConstantExpr::getVICmp(getPredicate(), C1, C2); else { - assert(getOpcode() == Instruction::VFCmp); - Replacement = ConstantExpr::getVFCmp(getPredicate(), C1, C2); + assert(getOpcode() == Instruction::FCmp); + Replacement = ConstantExpr::getFCmp(getPredicate(), C1, C2); } } else if (getNumOperands() == 2) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); if (C1 == From) C1 = To; if (C2 == From) C2 = To; - Replacement = ConstantExpr::get(getOpcode(), C1, C2); + Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData); } else { - assert(0 && "Unknown ConstantExpr type!"); + llvm_unreachable("Unknown ConstantExpr type!"); return; } @@ -3019,20 +2136,3 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, // Delete the old constant! destroyConstant(); } - -void MDNode::replaceElement(Value *From, Value *To) { - SmallVector<Value*, 4> Values; - Values.reserve(getNumElements()); // Build replacement array... - for (unsigned i = 0, e = getNumElements(); i != e; ++i) { - Value *Val = getElement(i); - if (Val == From) Val = To; - Values.push_back(Val); - } - - MDNode *Replacement = MDNode::get(&Values[0], Values.size()); - assert(Replacement != this && "I didn't contain From!"); - - uncheckedReplaceAllUsesWith(Replacement); - - destroyConstant(); -} diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h new file mode 100644 index 000000000000..526b4b1b7ee3 --- /dev/null +++ b/lib/VMCore/ConstantsContext.h @@ -0,0 +1,787 @@ +//===-- ConstantsContext.h - Constants-related Context Interals -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines various helper methods and classes used by +// LLVMContextImpl for creating and managing constants. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CONSTANTSCONTEXT_H +#define LLVM_CONSTANTSCONTEXT_H + +#include "llvm/Instructions.h" +#include "llvm/Operator.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/System/Mutex.h" +#include "llvm/System/RWMutex.h" +#include <map> + +namespace llvm { +template<class ValType> +struct ConstantTraits; + +/// UnaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement unary constant exprs. +class UnaryConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } + UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) + : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { + Op<0>() = C; + } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// BinaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement binary constant exprs. +class BinaryConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) + : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + SubclassOptionalData = Flags; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// SelectConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement select constant exprs. +class SelectConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), + Instruction::ExtractElement, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ShuffleVectorConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(VectorType::get( + cast<VectorType>(C1->getType())->getElementType(), + cast<VectorType>(C3->getType())->getNumElements()), + Instruction::ShuffleVector, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractvalue constant exprs. +class ExtractValueConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } + ExtractValueConstantExpr(Constant *Agg, + const SmallVector<unsigned, 4> &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), + Indices(IdxList) { + Op<0>() = Agg; + } + + /// Indices - These identify which value to extract. + const SmallVector<unsigned, 4> Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertvalue constant exprs. +class InsertValueConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 2); + } + InsertValueConstantExpr(Constant *Agg, Constant *Val, + const SmallVector<unsigned, 4> &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), + Indices(IdxList) { + Op<0>() = Agg; + Op<1>() = Val; + } + + /// Indices - These identify the position for the insertion. + const SmallVector<unsigned, 4> Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + + +/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is +/// used behind the scenes to implement getelementpr constant exprs. +class GetElementPtrConstantExpr : public ConstantExpr { + GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList, + const Type *DestTy); +public: + static GetElementPtrConstantExpr *Create(Constant *C, + const std::vector<Constant*>&IdxList, + const Type *DestTy, + unsigned Flags) { + GetElementPtrConstantExpr *Result = + new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); + Result->SubclassOptionalData = Flags; + return Result; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +// CompareConstantExpr - This class is private to Constants.cpp, and is used +// behind the scenes to implement ICmp and FCmp constant expressions. This is +// needed in order to store the predicate value for these instructions. +struct CompareConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + unsigned short predicate; + CompareConstantExpr(const Type *ty, Instruction::OtherOps opc, + unsigned short pred, Constant* LHS, Constant* RHS) + : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { + Op<0>() = LHS; + Op<1>() = RHS; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +template <> +struct OperandTraits<UnaryConstantExpr> : public FixedNumOperandTraits<1> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) + +template <> +struct OperandTraits<BinaryConstantExpr> : public FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) + +template <> +struct OperandTraits<SelectConstantExpr> : public FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) + +template <> +struct OperandTraits<ExtractElementConstantExpr> : public FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) + +template <> +struct OperandTraits<InsertElementConstantExpr> : public FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) + +template <> +struct OperandTraits<ShuffleVectorConstantExpr> : public FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) + +template <> +struct OperandTraits<ExtractValueConstantExpr> : public FixedNumOperandTraits<1> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) + +template <> +struct OperandTraits<InsertValueConstantExpr> : public FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) + +template <> +struct OperandTraits<GetElementPtrConstantExpr> : public VariadicOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) + + +template <> +struct OperandTraits<CompareConstantExpr> : public FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) + +struct ExprMapKeyType { + typedef SmallVector<unsigned, 4> IndexList; + + ExprMapKeyType(unsigned opc, + const std::vector<Constant*> &ops, + unsigned short flags = 0, + unsigned short optionalflags = 0, + const IndexList &inds = IndexList()) + : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), + operands(ops), indices(inds) {} + uint8_t opcode; + uint8_t subclassoptionaldata; + uint16_t subclassdata; + std::vector<Constant*> operands; + IndexList indices; + bool operator==(const ExprMapKeyType& that) const { + return this->opcode == that.opcode && + this->subclassdata == that.subclassdata && + this->subclassoptionaldata == that.subclassoptionaldata && + this->operands == that.operands && + this->indices == that.indices; + } + bool operator<(const ExprMapKeyType & that) const { + if (this->opcode != that.opcode) return this->opcode < that.opcode; + if (this->operands != that.operands) return this->operands < that.operands; + if (this->subclassdata != that.subclassdata) + return this->subclassdata < that.subclassdata; + if (this->subclassoptionaldata != that.subclassoptionaldata) + return this->subclassoptionaldata < that.subclassoptionaldata; + if (this->indices != that.indices) return this->indices < that.indices; + return false; + } + + bool operator!=(const ExprMapKeyType& that) const { + return !(*this == that); + } +}; + +// The number of operands for each ConstantCreator::create method is +// determined by the ConstantTraits template. +// ConstantCreator - A class that is used to create constants by +// ValueMap*. This class should be partially specialized if there is +// something strange that needs to be done to interface to the ctor for the +// constant. +// +template<typename T, typename Alloc> +struct ConstantTraits< std::vector<T, Alloc> > { + static unsigned uses(const std::vector<T, Alloc>& v) { + return v.size(); + } +}; + +template<class ConstantClass, class TypeClass, class ValType> +struct ConstantCreator { + static ConstantClass *create(const TypeClass *Ty, const ValType &V) { + return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V); + } +}; + +template<class ConstantClass> +struct ConstantKeyData { + typedef void ValType; + static ValType getValType(ConstantClass *C) { + llvm_unreachable("Unknown Constant type!"); + } +}; + +template<> +struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { + static ConstantExpr *create(const Type *Ty, const ExprMapKeyType &V, + unsigned short pred = 0) { + if (Instruction::isCast(V.opcode)) + return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); + if ((V.opcode >= Instruction::BinaryOpsBegin && + V.opcode < Instruction::BinaryOpsEnd)) + return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1], + V.subclassoptionaldata); + if (V.opcode == Instruction::Select) + return new SelectConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::ExtractElement) + return new ExtractElementConstantExpr(V.operands[0], V.operands[1]); + if (V.opcode == Instruction::InsertElement) + return new InsertElementConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::ShuffleVector) + return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1], + V.operands[2]); + if (V.opcode == Instruction::InsertValue) + return new InsertValueConstantExpr(V.operands[0], V.operands[1], + V.indices, Ty); + if (V.opcode == Instruction::ExtractValue) + return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); + if (V.opcode == Instruction::GetElementPtr) { + std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end()); + return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty, + V.subclassoptionaldata); + } + + // The compare instructions are weird. We have to encode the predicate + // value and it is combined with the instruction opcode by multiplying + // the opcode by one hundred. We must decode this to get the predicate. + if (V.opcode == Instruction::ICmp) + return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata, + V.operands[0], V.operands[1]); + if (V.opcode == Instruction::FCmp) + return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, + V.operands[0], V.operands[1]); + llvm_unreachable("Invalid ConstantExpr!"); + return 0; + } +}; + +template<> +struct ConstantKeyData<ConstantExpr> { + typedef ExprMapKeyType ValType; + static ValType getValType(ConstantExpr *CE) { + std::vector<Constant*> Operands; + Operands.reserve(CE->getNumOperands()); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) + Operands.push_back(cast<Constant>(CE->getOperand(i))); + return ExprMapKeyType(CE->getOpcode(), Operands, + CE->isCompare() ? CE->getPredicate() : 0, + CE->getRawSubclassOptionalData(), + CE->hasIndices() ? + CE->getIndices() : SmallVector<unsigned, 4>()); + } +}; + +// ConstantAggregateZero does not take extra "value" argument... +template<class ValType> +struct ConstantCreator<ConstantAggregateZero, Type, ValType> { + static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ + return new ConstantAggregateZero(Ty); + } +}; + +template<> +struct ConstantKeyData<ConstantVector> { + typedef std::vector<Constant*> ValType; + static ValType getValType(ConstantVector *CP) { + std::vector<Constant*> Elements; + Elements.reserve(CP->getNumOperands()); + for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) + Elements.push_back(CP->getOperand(i)); + return Elements; + } +}; + +template<> +struct ConstantKeyData<ConstantAggregateZero> { + typedef char ValType; + static ValType getValType(ConstantAggregateZero *C) { + return 0; + } +}; + +template<> +struct ConstantKeyData<ConstantArray> { + typedef std::vector<Constant*> ValType; + static ValType getValType(ConstantArray *CA) { + std::vector<Constant*> Elements; + Elements.reserve(CA->getNumOperands()); + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + Elements.push_back(cast<Constant>(CA->getOperand(i))); + return Elements; + } +}; + +template<> +struct ConstantKeyData<ConstantStruct> { + typedef std::vector<Constant*> ValType; + static ValType getValType(ConstantStruct *CS) { + std::vector<Constant*> Elements; + Elements.reserve(CS->getNumOperands()); + for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) + Elements.push_back(cast<Constant>(CS->getOperand(i))); + return Elements; + } +}; + +// ConstantPointerNull does not take extra "value" argument... +template<class ValType> +struct ConstantCreator<ConstantPointerNull, PointerType, ValType> { + static ConstantPointerNull *create(const PointerType *Ty, const ValType &V){ + return new ConstantPointerNull(Ty); + } +}; + +template<> +struct ConstantKeyData<ConstantPointerNull> { + typedef char ValType; + static ValType getValType(ConstantPointerNull *C) { + return 0; + } +}; + +// UndefValue does not take extra "value" argument... +template<class ValType> +struct ConstantCreator<UndefValue, Type, ValType> { + static UndefValue *create(const Type *Ty, const ValType &V) { + return new UndefValue(Ty); + } +}; + +template<> +struct ConstantKeyData<UndefValue> { + typedef char ValType; + static ValType getValType(UndefValue *C) { + return 0; + } +}; + +template<class ValType, class TypeClass, class ConstantClass, + bool HasLargeKey = false /*true for arrays and structs*/ > +class ValueMap : public AbstractTypeUser { +public: + typedef std::pair<const TypeClass*, ValType> MapKey; + typedef std::map<MapKey, ConstantClass *> MapTy; + typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy; + typedef std::map<const DerivedType*, typename MapTy::iterator> + AbstractTypeMapTy; +private: + /// Map - This is the main map from the element descriptor to the Constants. + /// This is the primary way we avoid creating two of the same shape + /// constant. + MapTy Map; + + /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping + /// from the constants to their element in Map. This is important for + /// removal of constants from the array, which would otherwise have to scan + /// through the map with very large keys. + InverseMapTy InverseMap; + + /// AbstractTypeMap - Map for abstract type constants. + /// + AbstractTypeMapTy AbstractTypeMap; + + /// ValueMapLock - Mutex for this map. + sys::SmartMutex<true> ValueMapLock; + +public: + // NOTE: This function is not locked. It is the caller's responsibility + // to enforce proper synchronization. + typename MapTy::iterator map_begin() { return Map.begin(); } + typename MapTy::iterator map_end() { return Map.end(); } + + void freeConstants() { + for (typename MapTy::iterator I=Map.begin(), E=Map.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + } + + /// InsertOrGetItem - Return an iterator for the specified element. + /// If the element exists in the map, the returned iterator points to the + /// entry and Exists=true. If not, the iterator points to the newly + /// inserted entry and returns Exists=false. Newly inserted entries have + /// I->second == 0, and should be filled in. + /// NOTE: This function is not locked. It is the caller's responsibility + // to enforce proper synchronization. + typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *> + &InsertVal, + bool &Exists) { + std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal); + Exists = !IP.second; + return IP.first; + } + +private: + typename MapTy::iterator FindExistingElement(ConstantClass *CP) { + if (HasLargeKey) { + typename InverseMapTy::iterator IMI = InverseMap.find(CP); + assert(IMI != InverseMap.end() && IMI->second != Map.end() && + IMI->second->second == CP && + "InverseMap corrupt!"); + return IMI->second; + } + + typename MapTy::iterator I = + Map.find(MapKey(static_cast<const TypeClass*>(CP->getRawType()), + ConstantKeyData<ConstantClass>::getValType(CP))); + if (I == Map.end() || I->second != CP) { + // FIXME: This should not use a linear scan. If this gets to be a + // performance problem, someone should look at this. + for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) + /* empty */; + } + return I; + } + + void AddAbstractTypeUser(const Type *Ty, typename MapTy::iterator I) { + // If the type of the constant is abstract, make sure that an entry + // exists for it in the AbstractTypeMap. + if (Ty->isAbstract()) { + const DerivedType *DTy = static_cast<const DerivedType *>(Ty); + typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(DTy); + + if (TI == AbstractTypeMap.end()) { + // Add ourselves to the ATU list of the type. + cast<DerivedType>(DTy)->addAbstractTypeUser(this); + + AbstractTypeMap.insert(TI, std::make_pair(DTy, I)); + } + } + } + + ConstantClass* Create(const TypeClass *Ty, const ValType &V, + typename MapTy::iterator I) { + ConstantClass* Result = + ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); + + assert(Result->getType() == Ty && "Type specified is not correct!"); + I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); + + if (HasLargeKey) // Remember the reverse mapping if needed. + InverseMap.insert(std::make_pair(Result, I)); + + AddAbstractTypeUser(Ty, I); + + return Result; + } +public: + + /// getOrCreate - Return the specified constant from the map, creating it if + /// necessary. + ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { + sys::SmartScopedLock<true> Lock(ValueMapLock); + MapKey Lookup(Ty, V); + ConstantClass* Result = 0; + + typename MapTy::iterator I = Map.find(Lookup); + // Is it in the map? + if (I != Map.end()) + Result = I->second; + + if (!Result) { + // If no preexisting value, create one now... + Result = Create(Ty, V, I); + } + + return Result; + } + + void UpdateAbstractTypeMap(const DerivedType *Ty, + typename MapTy::iterator I) { + assert(AbstractTypeMap.count(Ty) && + "Abstract type not in AbstractTypeMap?"); + typename MapTy::iterator &ATMEntryIt = AbstractTypeMap[Ty]; + if (ATMEntryIt == I) { + // Yes, we are removing the representative entry for this type. + // See if there are any other entries of the same type. + typename MapTy::iterator TmpIt = ATMEntryIt; + + // First check the entry before this one... + if (TmpIt != Map.begin()) { + --TmpIt; + if (TmpIt->first.first != Ty) // Not the same type, move back... + ++TmpIt; + } + + // If we didn't find the same type, try to move forward... + if (TmpIt == ATMEntryIt) { + ++TmpIt; + if (TmpIt == Map.end() || TmpIt->first.first != Ty) + --TmpIt; // No entry afterwards with the same type + } + + // If there is another entry in the map of the same abstract type, + // update the AbstractTypeMap entry now. + if (TmpIt != ATMEntryIt) { + ATMEntryIt = TmpIt; + } else { + // Otherwise, we are removing the last instance of this type + // from the table. Remove from the ATM, and from user list. + cast<DerivedType>(Ty)->removeAbstractTypeUser(this); + AbstractTypeMap.erase(Ty); + } + } + } + + void remove(ConstantClass *CP) { + sys::SmartScopedLock<true> Lock(ValueMapLock); + typename MapTy::iterator I = FindExistingElement(CP); + assert(I != Map.end() && "Constant not found in constant table!"); + assert(I->second == CP && "Didn't find correct element?"); + + if (HasLargeKey) // Remember the reverse mapping if needed. + InverseMap.erase(CP); + + // Now that we found the entry, make sure this isn't the entry that + // the AbstractTypeMap points to. + const TypeClass *Ty = I->first.first; + if (Ty->isAbstract()) + UpdateAbstractTypeMap(static_cast<const DerivedType *>(Ty), I); + + Map.erase(I); + } + + /// MoveConstantToNewSlot - If we are about to change C to be the element + /// specified by I, update our internal data structures to reflect this + /// fact. + /// NOTE: This function is not locked. It is the responsibility of the + /// caller to enforce proper synchronization if using this method. + void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { + // First, remove the old location of the specified constant in the map. + typename MapTy::iterator OldI = FindExistingElement(C); + assert(OldI != Map.end() && "Constant not found in constant table!"); + assert(OldI->second == C && "Didn't find correct element?"); + + // If this constant is the representative element for its abstract type, + // update the AbstractTypeMap so that the representative element is I. + if (C->getType()->isAbstract()) { + typename AbstractTypeMapTy::iterator ATI = + AbstractTypeMap.find(C->getType()); + assert(ATI != AbstractTypeMap.end() && + "Abstract type not in AbstractTypeMap?"); + if (ATI->second == OldI) + ATI->second = I; + } + + // Remove the old entry from the map. + Map.erase(OldI); + + // Update the inverse map so that we know that this constant is now + // located at descriptor I. + if (HasLargeKey) { + assert(I->second == C && "Bad inversemap entry!"); + InverseMap[C] = I; + } + } + + void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { + sys::SmartScopedLock<true> Lock(ValueMapLock); + typename AbstractTypeMapTy::iterator I = AbstractTypeMap.find(OldTy); + + assert(I != AbstractTypeMap.end() && + "Abstract type not in AbstractTypeMap?"); + + // Convert a constant at a time until the last one is gone. The last one + // leaving will remove() itself, causing the AbstractTypeMapEntry to be + // eliminated eventually. + do { + ConstantClass *C = I->second->second; + MapKey Key(cast<TypeClass>(NewTy), + ConstantKeyData<ConstantClass>::getValType(C)); + + std::pair<typename MapTy::iterator, bool> IP = + Map.insert(std::make_pair(Key, C)); + if (IP.second) { + // The map didn't previously have an appropriate constant in the + // new type. + + // Remove the old entry. + typename MapTy::iterator OldI = + Map.find(MapKey(cast<TypeClass>(OldTy), IP.first->first.second)); + assert(OldI != Map.end() && "Constant not in map!"); + UpdateAbstractTypeMap(OldTy, OldI); + Map.erase(OldI); + + // Set the constant's type. This is done in place! + setType(C, NewTy); + + // Update the inverse map so that we know that this constant is now + // located at descriptor I. + if (HasLargeKey) + InverseMap[C] = IP.first; + + AddAbstractTypeUser(NewTy, IP.first); + } else { + // The map already had an appropriate constant in the new type, so + // there's no longer a need for the old constant. + C->uncheckedReplaceAllUsesWith(IP.first->second); + C->destroyConstant(); // This constant is now dead, destroy it. + } + I = AbstractTypeMap.find(OldTy); + } while (I != AbstractTypeMap.end()); + } + + // If the type became concrete without being refined to any other existing + // type, we just remove ourselves from the ATU list. + void typeBecameConcrete(const DerivedType *AbsTy) { + AbsTy->removeAbstractTypeUser(this); + } + + void dump() const { + DEBUG(errs() << "Constant.cpp: ValueMap\n"); + } +}; + +} + +#endif diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 6eb188907f56..bff308727fe1 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -25,6 +25,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/CallSite.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> #include <cstdlib> #include <cstring> @@ -93,12 +94,15 @@ int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { } void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name) { - std::string N(Name); - TypeSymbolTable &TST = unwrap(M)->getTypeSymbolTable(); - for (TypeSymbolTable::iterator I = TST.begin(), E = TST.end(); I != E; ++I) - if (I->first == N) - TST.remove(I); + + TypeSymbolTable::iterator I = TST.find(Name); + if (I != TST.end()) + TST.remove(I); +} + +LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { + return wrap(unwrap(M)->getTypeByName(Name)); } void LLVMDumpModule(LLVMModuleRef M) { @@ -111,19 +115,84 @@ void LLVMDumpModule(LLVMModuleRef M) { /*--.. Operations on all types (mostly) ....................................--*/ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { - return static_cast<LLVMTypeKind>(unwrap(Ty)->getTypeID()); + switch (unwrap(Ty)->getTypeID()) { + default: + assert(false && "Unhandled TypeID."); + case Type::VoidTyID: + return LLVMVoidTypeKind; + case Type::FloatTyID: + return LLVMFloatTypeKind; + case Type::DoubleTyID: + return LLVMDoubleTypeKind; + case Type::X86_FP80TyID: + return LLVMX86_FP80TypeKind; + case Type::FP128TyID: + return LLVMFP128TypeKind; + case Type::PPC_FP128TyID: + return LLVMPPC_FP128TypeKind; + case Type::LabelTyID: + return LLVMLabelTypeKind; + case Type::MetadataTyID: + return LLVMMetadataTypeKind; + case Type::IntegerTyID: + return LLVMIntegerTypeKind; + case Type::FunctionTyID: + return LLVMFunctionTypeKind; + case Type::StructTyID: + return LLVMStructTypeKind; + case Type::ArrayTyID: + return LLVMArrayTypeKind; + case Type::PointerTyID: + return LLVMPointerTypeKind; + case Type::OpaqueTyID: + return LLVMOpaqueTypeKind; + case Type::VectorTyID: + return LLVMVectorTypeKind; + } +} + +LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) { + return wrap(&unwrap(Ty)->getContext()); } /*--.. Operations on integer types .........................................--*/ -LLVMTypeRef LLVMInt1Type(void) { return (LLVMTypeRef) Type::Int1Ty; } -LLVMTypeRef LLVMInt8Type(void) { return (LLVMTypeRef) Type::Int8Ty; } -LLVMTypeRef LLVMInt16Type(void) { return (LLVMTypeRef) Type::Int16Ty; } -LLVMTypeRef LLVMInt32Type(void) { return (LLVMTypeRef) Type::Int32Ty; } -LLVMTypeRef LLVMInt64Type(void) { return (LLVMTypeRef) Type::Int64Ty; } +LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt1Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt8Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt16Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt32Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt64Ty(*unwrap(C)); +} +LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits) { + return wrap(IntegerType::get(*unwrap(C), NumBits)); +} +LLVMTypeRef LLVMInt1Type(void) { + return LLVMInt1TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt8Type(void) { + return LLVMInt8TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt16Type(void) { + return LLVMInt16TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt32Type(void) { + return LLVMInt32TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt64Type(void) { + return LLVMInt64TypeInContext(LLVMGetGlobalContext()); +} LLVMTypeRef LLVMIntType(unsigned NumBits) { - return wrap(IntegerType::get(NumBits)); + return LLVMIntTypeInContext(LLVMGetGlobalContext(), NumBits); } unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { @@ -132,11 +201,37 @@ unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { /*--.. Operations on real types ............................................--*/ -LLVMTypeRef LLVMFloatType(void) { return (LLVMTypeRef) Type::FloatTy; } -LLVMTypeRef LLVMDoubleType(void) { return (LLVMTypeRef) Type::DoubleTy; } -LLVMTypeRef LLVMX86FP80Type(void) { return (LLVMTypeRef) Type::X86_FP80Ty; } -LLVMTypeRef LLVMFP128Type(void) { return (LLVMTypeRef) Type::FP128Ty; } -LLVMTypeRef LLVMPPCFP128Type(void) { return (LLVMTypeRef) Type::PPC_FP128Ty; } +LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getFloatTy(*unwrap(C)); +} +LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getDoubleTy(*unwrap(C)); +} +LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getX86_FP80Ty(*unwrap(C)); +} +LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getFP128Ty(*unwrap(C)); +} +LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getPPC_FP128Ty(*unwrap(C)); +} + +LLVMTypeRef LLVMFloatType(void) { + return LLVMFloatTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMDoubleType(void) { + return LLVMDoubleTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMX86FP80Type(void) { + return LLVMX86FP80TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMFP128Type(void) { + return LLVMFP128TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMPPCFP128Type(void) { + return LLVMPPCFP128TypeInContext(LLVMGetGlobalContext()); +} /*--.. Operations on function types ........................................--*/ @@ -171,16 +266,23 @@ void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { /*--.. Operations on struct types ..........................................--*/ -LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, +LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, unsigned ElementCount, int Packed) { std::vector<const Type*> Tys; for (LLVMTypeRef *I = ElementTypes, *E = ElementTypes + ElementCount; I != E; ++I) Tys.push_back(unwrap(*I)); - return wrap(StructType::get(Tys, Packed != 0)); + return wrap(StructType::get(*unwrap(C), Tys, Packed != 0)); +} + +LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, + unsigned ElementCount, int Packed) { + return LLVMStructTypeInContext(LLVMGetGlobalContext(), ElementTypes, + ElementCount, Packed); } + unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) { return unwrap<StructType>(StructTy)->getNumElements(); } @@ -228,11 +330,24 @@ unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) { /*--.. Operations on other types ...........................................--*/ -LLVMTypeRef LLVMVoidType(void) { return (LLVMTypeRef) Type::VoidTy; } -LLVMTypeRef LLVMLabelType(void) { return (LLVMTypeRef) Type::LabelTy; } +LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) { + return wrap(Type::getVoidTy(*unwrap(C))); +} +LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C) { + return wrap(Type::getLabelTy(*unwrap(C))); +} +LLVMTypeRef LLVMOpaqueTypeInContext(LLVMContextRef C) { + return wrap(OpaqueType::get(*unwrap(C))); +} +LLVMTypeRef LLVMVoidType(void) { + return LLVMVoidTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMLabelType(void) { + return LLVMLabelTypeInContext(LLVMGetGlobalContext()); +} LLVMTypeRef LLVMOpaqueType(void) { - return wrap(llvm::OpaqueType::get()); + return LLVMOpaqueTypeInContext(LLVMGetGlobalContext()); } /*--.. Operations on type handles ..........................................--*/ @@ -263,7 +378,7 @@ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) { } const char *LLVMGetValueName(LLVMValueRef Val) { - return unwrap(Val)->getNameStart(); + return unwrap(Val)->getName().data(); } void LLVMSetValueName(LLVMValueRef Val, const char *Name) { @@ -274,6 +389,9 @@ void LLVMDumpValue(LLVMValueRef Val) { unwrap(Val)->dump(); } +void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { + unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); +} /*--.. Conversion functions ................................................--*/ @@ -284,6 +402,31 @@ void LLVMDumpValue(LLVMValueRef Val) { LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST) +/*--.. Operations on Uses ..................................................--*/ +LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val) { + Value *V = unwrap(Val); + Value::use_iterator I = V->use_begin(); + if (I == V->use_end()) + return 0; + return wrap(&(I.getUse())); +} + +LLVMUseIteratorRef LLVMGetNextUse(LLVMUseIteratorRef UR) { + return wrap(unwrap(UR)->getNext()); +} + +LLVMValueRef LLVMGetUser(LLVMUseIteratorRef UR) { + return wrap(unwrap(UR)->getUser()); +} + +LLVMValueRef LLVMGetUsedValue(LLVMUseIteratorRef UR) { + return wrap(unwrap(UR)->get()); +} + +/*--.. Operations on Users .................................................--*/ +LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { + return wrap(unwrap<User>(Val)->getOperand(Index)); +} /*--.. Operations on constants of any type .................................--*/ @@ -313,6 +456,11 @@ int LLVMIsUndef(LLVMValueRef Val) { return isa<UndefValue>(unwrap(Val)); } +LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) { + return + wrap(ConstantPointerNull::get(unwrap<PointerType>(Ty))); +} + /*--.. Operations on scalar constants ......................................--*/ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, @@ -320,63 +468,84 @@ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), N, SignExtend != 0)); } -static const fltSemantics &SemanticsForType(Type *Ty) { - assert(Ty->isFloatingPoint() && "Type is not floating point!"); - if (Ty == Type::FloatTy) - return APFloat::IEEEsingle; - if (Ty == Type::DoubleTy) - return APFloat::IEEEdouble; - if (Ty == Type::X86_FP80Ty) - return APFloat::x87DoubleExtended; - if (Ty == Type::FP128Ty) - return APFloat::IEEEquad; - if (Ty == Type::PPC_FP128Ty) - return APFloat::PPCDoubleDouble; - return APFloat::Bogus; +LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[], + uint8_t Radix) { + return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str), + Radix)); +} + +LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char Str[], + unsigned SLen, uint8_t Radix) { + return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str, SLen), + Radix)); } LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N) { - APFloat APN(N); - bool ignored; - APN.convert(SemanticsForType(unwrap(RealTy)), APFloat::rmNearestTiesToEven, - &ignored); - return wrap(ConstantFP::get(APN)); + return wrap(ConstantFP::get(unwrap(RealTy), N)); } LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text) { - return wrap(ConstantFP::get(APFloat(SemanticsForType(unwrap(RealTy)), Text))); + return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Text))); +} + +LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[], + unsigned SLen) { + return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen))); +} + +unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) { + return unwrap<ConstantInt>(ConstantVal)->getZExtValue(); +} + +long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal) { + return unwrap<ConstantInt>(ConstantVal)->getSExtValue(); } /*--.. Operations on composite constants ...................................--*/ -LLVMValueRef LLVMConstString(const char *Str, unsigned Length, - int DontNullTerminate) { +LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, + unsigned Length, int DontNullTerminate) { /* Inverted the sense of AddNull because ', 0)' is a better mnemonic for null termination than ', 1)'. */ - return wrap(ConstantArray::get(std::string(Str, Length), + return wrap(ConstantArray::get(*unwrap(C), std::string(Str, Length), DontNullTerminate == 0)); } +LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, + LLVMValueRef *ConstantVals, + unsigned Count, int Packed) { + return wrap(ConstantStruct::get(*unwrap(C), + unwrap<Constant>(ConstantVals, Count), + Count, Packed != 0)); +} +LLVMValueRef LLVMConstString(const char *Str, unsigned Length, + int DontNullTerminate) { + return LLVMConstStringInContext(LLVMGetGlobalContext(), Str, Length, + DontNullTerminate); +} LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), unwrap<Constant>(ConstantVals, Length), Length)); } - LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, int Packed) { - return wrap(ConstantStruct::get(unwrap<Constant>(ConstantVals, Count), - Count, Packed != 0)); + return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count, + Packed); } LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { - return wrap(ConstantVector::get(unwrap<Constant>(ScalarConstantVals, Size), - Size)); + return wrap(ConstantVector::get( + unwrap<Constant>(ScalarConstantVals, Size), Size)); } /*--.. Constant expressions ................................................--*/ +LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) { + return (LLVMOpcode)unwrap<ConstantExpr>(ConstantVal)->getOpcode(); +} + LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty) { return wrap(ConstantExpr::getAlignOf(unwrap(Ty))); } @@ -386,70 +555,120 @@ LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) { } LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNeg(unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNeg( + unwrap<Constant>(ConstantVal))); +} + +LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getFNeg( + unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal) { - return wrap(ConstantExpr::getNot(unwrap<Constant>(ConstantVal))); + return wrap(ConstantExpr::getNot( + unwrap<Constant>(ConstantVal))); } LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAdd(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAdd( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } +LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNSWAdd( + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFAdd( + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSub(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSub( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } +LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFSub(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getMul(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getMul( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } +LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFMul( + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getUDiv(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getUDiv( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSDiv(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSDiv( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } +LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getExactSDiv( + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFDiv(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFDiv( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getURem(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getURem( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getSRem(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getSRem( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getFRem(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getFRem( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAnd(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAnd( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getOr(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getOr( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getXor(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getXor( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } @@ -468,55 +687,73 @@ LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate, } LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getShl(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getShl( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getLShr(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getLShr( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getAShr(unwrap<Constant>(LHSConstant), + return wrap(ConstantExpr::getAShr( + unwrap<Constant>(LHSConstant), unwrap<Constant>(RHSConstant))); } LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, LLVMValueRef *ConstantIndices, unsigned NumIndices) { - return wrap(ConstantExpr::getGetElementPtr(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getGetElementPtr( + unwrap<Constant>(ConstantVal), unwrap<Constant>(ConstantIndices, NumIndices), NumIndices)); } +LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, + LLVMValueRef *ConstantIndices, + unsigned NumIndices) { + Constant* Val = unwrap<Constant>(ConstantVal); + Constant** Idxs = unwrap<Constant>(ConstantIndices, NumIndices); + return wrap(ConstantExpr::getInBoundsGetElementPtr(Val, Idxs, NumIndices)); +} + LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getTrunc(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getTrunc( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getSExt(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getSExt( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getZExt(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getZExt( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPTrunc(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPTrunc( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPExtend(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPExtend( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getUIToFP(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getUIToFP( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } @@ -531,43 +768,92 @@ LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { } LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getFPToSI(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getFPToSI( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getPtrToInt(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getPtrToInt( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getIntToPtr(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getIntToPtr( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { - return wrap(ConstantExpr::getBitCast(unwrap<Constant>(ConstantVal), + return wrap(ConstantExpr::getBitCast( + unwrap<Constant>(ConstantVal), unwrap(ToType))); } +LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getZExtOrBitCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getSExtOrBitCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getTruncOrBitCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getPointerCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType, + unsigned isSigned) { + return wrap(ConstantExpr::getIntegerCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType), + isSigned)); +} + +LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPCast( + unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition, LLVMValueRef ConstantIfTrue, LLVMValueRef ConstantIfFalse) { - return wrap(ConstantExpr::getSelect(unwrap<Constant>(ConstantCondition), + return wrap(ConstantExpr::getSelect( + unwrap<Constant>(ConstantCondition), unwrap<Constant>(ConstantIfTrue), unwrap<Constant>(ConstantIfFalse))); } LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant, LLVMValueRef IndexConstant) { - return wrap(ConstantExpr::getExtractElement(unwrap<Constant>(VectorConstant), + return wrap(ConstantExpr::getExtractElement( + unwrap<Constant>(VectorConstant), unwrap<Constant>(IndexConstant))); } LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef ElementValueConstant, LLVMValueRef IndexConstant) { - return wrap(ConstantExpr::getInsertElement(unwrap<Constant>(VectorConstant), + return wrap(ConstantExpr::getInsertElement( + unwrap<Constant>(VectorConstant), unwrap<Constant>(ElementValueConstant), unwrap<Constant>(IndexConstant))); } @@ -575,29 +861,33 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant) { - return wrap(ConstantExpr::getShuffleVector(unwrap<Constant>(VectorAConstant), + return wrap(ConstantExpr::getShuffleVector( + unwrap<Constant>(VectorAConstant), unwrap<Constant>(VectorBConstant), unwrap<Constant>(MaskConstant))); } LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx) { - return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant), + return wrap(ConstantExpr::getExtractValue( + unwrap<Constant>(AggConstant), IdxList, NumIdx)); } LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, LLVMValueRef ElementValueConstant, unsigned *IdxList, unsigned NumIdx) { - return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant), + return wrap(ConstantExpr::getInsertValue( + unwrap<Constant>(AggConstant), unwrap<Constant>(ElementValueConstant), IdxList, NumIdx)); } LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, - const char *Constraints, int HasSideEffects) { + const char *Constraints, int HasSideEffects, + int IsMsAsm) { return wrap(InlineAsm::get(dyn_cast<FunctionType>(unwrap(Ty)), AsmString, - Constraints, HasSideEffects)); + Constraints, HasSideEffects, IsMsAsm)); } /*--.. Operations on global variables, functions, and aliases (globals) ....--*/ @@ -611,12 +901,97 @@ int LLVMIsDeclaration(LLVMValueRef Global) { } LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { - return static_cast<LLVMLinkage>(unwrap<GlobalValue>(Global)->getLinkage()); + switch (unwrap<GlobalValue>(Global)->getLinkage()) { + default: + assert(false && "Unhandled Linkage Type."); + case GlobalValue::ExternalLinkage: + return LLVMExternalLinkage; + case GlobalValue::AvailableExternallyLinkage: + return LLVMAvailableExternallyLinkage; + case GlobalValue::LinkOnceAnyLinkage: + return LLVMLinkOnceAnyLinkage; + case GlobalValue::LinkOnceODRLinkage: + return LLVMLinkOnceODRLinkage; + case GlobalValue::WeakAnyLinkage: + return LLVMWeakAnyLinkage; + case GlobalValue::WeakODRLinkage: + return LLVMWeakODRLinkage; + case GlobalValue::AppendingLinkage: + return LLVMAppendingLinkage; + case GlobalValue::InternalLinkage: + return LLVMInternalLinkage; + case GlobalValue::PrivateLinkage: + return LLVMPrivateLinkage; + case GlobalValue::LinkerPrivateLinkage: + return LLVMLinkerPrivateLinkage; + case GlobalValue::DLLImportLinkage: + return LLVMDLLImportLinkage; + case GlobalValue::DLLExportLinkage: + return LLVMDLLExportLinkage; + case GlobalValue::ExternalWeakLinkage: + return LLVMExternalWeakLinkage; + case GlobalValue::GhostLinkage: + return LLVMGhostLinkage; + case GlobalValue::CommonLinkage: + return LLVMCommonLinkage; + } + + // Should never get here. + return static_cast<LLVMLinkage>(0); } void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { - unwrap<GlobalValue>(Global) - ->setLinkage(static_cast<GlobalValue::LinkageTypes>(Linkage)); + GlobalValue *GV = unwrap<GlobalValue>(Global); + + switch (Linkage) { + default: + assert(false && "Unhandled Linkage Type."); + case LLVMExternalLinkage: + GV->setLinkage(GlobalValue::ExternalLinkage); + break; + case LLVMAvailableExternallyLinkage: + GV->setLinkage(GlobalValue::AvailableExternallyLinkage); + break; + case LLVMLinkOnceAnyLinkage: + GV->setLinkage(GlobalValue::LinkOnceAnyLinkage); + break; + case LLVMLinkOnceODRLinkage: + GV->setLinkage(GlobalValue::LinkOnceODRLinkage); + break; + case LLVMWeakAnyLinkage: + GV->setLinkage(GlobalValue::WeakAnyLinkage); + break; + case LLVMWeakODRLinkage: + GV->setLinkage(GlobalValue::WeakODRLinkage); + break; + case LLVMAppendingLinkage: + GV->setLinkage(GlobalValue::AppendingLinkage); + break; + case LLVMInternalLinkage: + GV->setLinkage(GlobalValue::InternalLinkage); + break; + case LLVMPrivateLinkage: + GV->setLinkage(GlobalValue::PrivateLinkage); + break; + case LLVMLinkerPrivateLinkage: + GV->setLinkage(GlobalValue::LinkerPrivateLinkage); + break; + case LLVMDLLImportLinkage: + GV->setLinkage(GlobalValue::DLLImportLinkage); + break; + case LLVMDLLExportLinkage: + GV->setLinkage(GlobalValue::DLLExportLinkage); + break; + case LLVMExternalWeakLinkage: + GV->setLinkage(GlobalValue::ExternalWeakLinkage); + break; + case LLVMGhostLinkage: + GV->setLinkage(GlobalValue::GhostLinkage); + break; + case LLVMCommonLinkage: + GV->setLinkage(GlobalValue::CommonLinkage); + break; + } } const char *LLVMGetSection(LLVMValueRef Global) { @@ -648,9 +1023,8 @@ void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes) { /*--.. Operations on global variables ......................................--*/ LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { - return wrap(new GlobalVariable(unwrap(Ty), false, - GlobalValue::ExternalLinkage, 0, Name, - unwrap(M))); + return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, + GlobalValue::ExternalLinkage, 0, Name)); } LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) { @@ -694,7 +1068,10 @@ void LLVMDeleteGlobal(LLVMValueRef GlobalVar) { } LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) { - return wrap(unwrap<GlobalVariable>(GlobalVar)->getInitializer()); + GlobalVariable* GV = unwrap<GlobalVariable>(GlobalVar); + if ( !GV->hasInitializer() ) + return 0; + return wrap(GV->getInitializer()); } void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) { @@ -785,7 +1162,8 @@ unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) { } void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { - return unwrap<Function>(Fn)->setCallingConv(CC); + return unwrap<Function>(Fn)->setCallingConv( + static_cast<CallingConv::ID>(CC)); } const char *LLVMGetGC(LLVMValueRef Fn) { @@ -815,6 +1193,13 @@ void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { Func->setAttributes(PALnew); } +LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + const AttrListPtr PAL = Func->getAttributes(); + Attributes attr = PAL.getFnAttributes(); + return (LLVMAttribute)attr; +} + /*--.. Operations on parameters ............................................--*/ unsigned LLVMCountParams(LLVMValueRef FnRef) { @@ -881,6 +1266,14 @@ void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) { unwrap<Argument>(Arg)->removeAttr(PA); } +LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) { + Argument *A = unwrap<Argument>(Arg); + Attributes attr = A->getParent()->getAttributes().getParamAttributes( + A->getArgNo()+1); + return (LLVMAttribute)attr; +} + + void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { unwrap<Argument>(Arg)->addAttr( Attribute::constructAlignmentFromInt(align)); @@ -950,15 +1343,26 @@ LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) { return wrap(--I); } +LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C, + LLVMValueRef FnRef, + const char *Name) { + return wrap(BasicBlock::Create(*unwrap(C), Name, unwrap<Function>(FnRef))); +} + LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) { - return wrap(BasicBlock::Create(Name, unwrap<Function>(FnRef))); + return LLVMAppendBasicBlockInContext(LLVMGetGlobalContext(), FnRef, Name); +} + +LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C, + LLVMBasicBlockRef BBRef, + const char *Name) { + BasicBlock *BB = unwrap(BBRef); + return wrap(BasicBlock::Create(*unwrap(C), Name, BB->getParent(), BB)); } -LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBBRef, +LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef BBRef, const char *Name) { - BasicBlock *InsertBeforeBB = unwrap(InsertBeforeBBRef); - return wrap(BasicBlock::Create(Name, InsertBeforeBB->getParent(), - InsertBeforeBB)); + return LLVMInsertBasicBlockInContext(LLVMGetGlobalContext(), BBRef, Name); } void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) { @@ -1011,17 +1415,17 @@ unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) { return CI->getCallingConv(); else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) return II->getCallingConv(); - assert(0 && "LLVMGetInstructionCallConv applies only to call and invoke!"); + llvm_unreachable("LLVMGetInstructionCallConv applies only to call and invoke!"); return 0; } void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { Value *V = unwrap(Instr); if (CallInst *CI = dyn_cast<CallInst>(V)) - return CI->setCallingConv(CC); + return CI->setCallingConv(static_cast<CallingConv::ID>(CC)); else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) - return II->setCallingConv(CC); - assert(0 && "LLVMSetInstructionCallConv applies only to call and invoke!"); + return II->setCallingConv(static_cast<CallingConv::ID>(CC)); + llvm_unreachable("LLVMSetInstructionCallConv applies only to call and invoke!"); } void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, @@ -1080,8 +1484,12 @@ LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index) { /*===-- Instruction builders ----------------------------------------------===*/ +LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C) { + return wrap(new IRBuilder<>(*unwrap(C))); +} + LLVMBuilderRef LLVMCreateBuilder(void) { - return wrap(new IRBuilder<>()); + return LLVMCreateBuilderInContext(LLVMGetGlobalContext()); } void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, @@ -1113,6 +1521,11 @@ void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr) { unwrap(Builder)->Insert(unwrap<Instruction>(Instr)); } +void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr, + const char *Name) { + unwrap(Builder)->Insert(unwrap<Instruction>(Instr), Name); +} + void LLVMDisposeBuilder(LLVMBuilderRef Builder) { delete unwrap(Builder); } @@ -1127,6 +1540,11 @@ LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { return wrap(unwrap(B)->CreateRet(unwrap(V))); } +LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef B, LLVMValueRef *RetVals, + unsigned N) { + return wrap(unwrap(B)->CreateAggregateRet(unwrap(RetVals), N)); +} + LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { return wrap(unwrap(B)->CreateBr(unwrap(Dest))); } @@ -1170,16 +1588,36 @@ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name)); } +LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNSWAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFAdd(unwrap(LHS), unwrap(RHS), Name)); +} + LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name)); } +LLVMValueRef LLVMBuildFSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFSub(unwrap(LHS), unwrap(RHS), Name)); +} + LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name)); } +LLVMValueRef LLVMBuildFMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFMul(unwrap(LHS), unwrap(RHS), Name)); +} + LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name)); @@ -1190,6 +1628,11 @@ LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name)); } +LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreateExactSDiv(unwrap(LHS), unwrap(RHS), Name)); +} + LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name) { return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name)); @@ -1244,6 +1687,10 @@ LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNeg(unwrap(V), Name)); } +LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name)); +} + LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); } @@ -1292,6 +1739,28 @@ LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, unwrap(Indices) + NumIndices, Name)); } +LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name) { + return wrap(unwrap(B)->CreateInBoundsGEP(unwrap(Pointer), unwrap(Indices), + unwrap(Indices) + NumIndices, Name)); +} + +LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + unsigned Idx, const char *Name) { + return wrap(unwrap(B)->CreateStructGEP(unwrap(Pointer), Idx, Name)); +} + +LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str, + const char *Name) { + return wrap(unwrap(B)->CreateGlobalString(Str, Name)); +} + +LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str, + const char *Name) { + return wrap(unwrap(B)->CreateGlobalStringPtr(Str, Name)); +} + /*--.. Casts ...............................................................--*/ LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, @@ -1354,6 +1823,39 @@ LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); } +LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSExtOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateTruncOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreatePointerCast(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPCast(unwrap(Val), unwrap(DestTy), Name)); +} + /*--.. Comparisons .........................................................--*/ LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, @@ -1427,6 +1929,21 @@ LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal, Index, Name)); } +LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateIsNotNull(unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name)); +} + /*===-- Module providers --------------------------------------------------===*/ diff --git a/lib/VMCore/Dominators.cpp b/lib/VMCore/Dominators.cpp index 735a70c50927..b49faf84dcea 100644 --- a/lib/VMCore/Dominators.cpp +++ b/lib/VMCore/Dominators.cpp @@ -23,22 +23,20 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/DominatorInternals.h" #include "llvm/Instructions.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/CommandLine.h" #include <algorithm> using namespace llvm; -namespace llvm { -static std::ostream &operator<<(std::ostream &o, - const std::set<BasicBlock*> &BBs) { - for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); - I != E; ++I) - if (*I) - WriteAsOperand(o, *I, false); - else - o << " <<exit node>>"; - return o; -} -} +// Always verify dominfo if expensive checking is enabled. +#ifdef XDEBUG +bool VerifyDomInfo = true; +#else +bool VerifyDomInfo = false; +#endif +static cl::opt<bool,true> +VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), + cl::desc("Verify dominator info (time consuming)")); //===----------------------------------------------------------------------===// // DominatorTree Implementation @@ -61,6 +59,47 @@ bool DominatorTree::runOnFunction(Function &F) { return false; } +void DominatorTree::verifyAnalysis() const { + if (!VerifyDomInfo) return; + + Function &F = *getRoot()->getParent(); + + DominatorTree OtherDT; + OtherDT.getBase().recalculate(F); + assert(!compare(OtherDT) && "Invalid DominatorTree info!"); +} + +void DominatorTree::print(raw_ostream &OS, const Module *) const { + DT->print(OS); +} + +// dominates - Return true if A dominates a use in B. This performs the +// special checks necessary if A and B are in the same basic block. +bool DominatorTree::dominates(const Instruction *A, const Instruction *B) const{ + const BasicBlock *BBA = A->getParent(), *BBB = B->getParent(); + + // If A is an invoke instruction, its value is only available in this normal + // successor block. + if (const InvokeInst *II = dyn_cast<InvokeInst>(A)) + BBA = II->getNormalDest(); + + if (BBA != BBB) return dominates(BBA, BBB); + + // It is not possible to determine dominance between two PHI nodes + // based on their ordering. + if (isa<PHINode>(A) && isa<PHINode>(B)) + return false; + + // Loop through the basic block until we find A or B. + BasicBlock::const_iterator I = BBA->begin(); + for (; &*I != A && &*I != B; ++I) + /*empty*/; + + return &*I == A; +} + + + //===----------------------------------------------------------------------===// // DominanceFrontier Implementation //===----------------------------------------------------------------------===// @@ -69,6 +108,17 @@ char DominanceFrontier::ID = 0; static RegisterPass<DominanceFrontier> G("domfrontier", "Dominance Frontier Construction", true, true); +void DominanceFrontier::verifyAnalysis() const { + if (!VerifyDomInfo) return; + + DominatorTree &DT = getAnalysis<DominatorTree>(); + + DominanceFrontier OtherDF; + const std::vector<BasicBlock*> &DTRoots = DT.getRoots(); + OtherDF.calculate(DT, DT.getNode(DTRoots[0])); + assert(!compare(OtherDF) && "Invalid DominanceFrontier info!"); +} + // NewBB is split and now it has one successor. Update dominace frontier to // reflect this change. void DominanceFrontier::splitBlock(BasicBlock *NewBB) { @@ -76,7 +126,7 @@ void DominanceFrontier::splitBlock(BasicBlock *NewBB) { && "NewBB should have a single successor!"); BasicBlock *NewBBSucc = NewBB->getTerminator()->getSuccessor(0); - std::vector<BasicBlock*> PredBlocks; + SmallVector<BasicBlock*, 8> PredBlocks; for (pred_iterator PI = pred_begin(NewBB), PE = pred_end(NewBB); PI != PE; ++PI) PredBlocks.push_back(*PI); @@ -153,7 +203,7 @@ void DominanceFrontier::splitBlock(BasicBlock *NewBB) { // Verify whether this block dominates a block in predblocks. If not, do // not update it. bool BlockDominatesAny = false; - for (std::vector<BasicBlock*>::const_iterator BI = PredBlocks.begin(), + for (SmallVectorImpl<BasicBlock*>::const_iterator BI = PredBlocks.begin(), BE = PredBlocks.end(); BI != BE; ++BI) { if (DT.dominates(FI, *BI)) { BlockDominatesAny = true; @@ -270,18 +320,24 @@ DominanceFrontier::calculate(const DominatorTree &DT, return *Result; } -void DominanceFrontierBase::print(std::ostream &o, const Module* ) const { +void DominanceFrontierBase::print(raw_ostream &OS, const Module* ) const { for (const_iterator I = begin(), E = end(); I != E; ++I) { - o << " DomFrontier for BB"; + OS << " DomFrontier for BB"; if (I->first) - WriteAsOperand(o, I->first, false); + WriteAsOperand(OS, I->first, false); else - o << " <<exit node>>"; - o << " is:\t" << I->second << "\n"; + OS << " <<exit node>>"; + OS << " is:\t"; + + const std::set<BasicBlock*> &BBs = I->second; + + for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); + I != E; ++I) + if (*I) + WriteAsOperand(OS, *I, false); + else + OS << " <<exit node>>"; + OS << "\n"; } } -void DominanceFrontierBase::dump() { - print (llvm::cerr); -} - diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index eeade051ac53..8ad885c4c23d 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -14,6 +14,7 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" @@ -35,7 +36,7 @@ template class SymbolTableListTraits<BasicBlock, Function>; // Argument Implementation //===----------------------------------------------------------------------===// -Argument::Argument(const Type *Ty, const std::string &Name, Function *Par) +Argument::Argument(const Type *Ty, const Twine &Name, Function *Par) : Value(Ty, Value::ArgumentVal) { Parent = 0; @@ -114,10 +115,8 @@ void Argument::removeAttr(Attributes attr) { // Helper Methods in Function //===----------------------------------------------------------------------===// -LLVMContext* Function::getContext() { - Module* M = getParent(); - if (M) return &M->getContext(); - return 0; +LLVMContext &Function::getContext() const { + return getType()->getContext(); } const FunctionType *Function::getFunctionType() const { @@ -145,7 +144,7 @@ void Function::eraseFromParent() { //===----------------------------------------------------------------------===// Function::Function(const FunctionType *Ty, LinkageTypes Linkage, - const std::string &name, Module *ParentModule) + const Twine &name, Module *ParentModule) : GlobalValue(PointerType::getUnqual(Ty), Value::FunctionVal, 0, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && @@ -183,7 +182,7 @@ void Function::BuildLazyArguments() const { // Create the arguments vector, all arguments start out unnamed. const FunctionType *FT = getFunctionType(); for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { - assert(FT->getParamType(i) != Type::VoidTy && + assert(FT->getParamType(i) != Type::getVoidTy(FT->getContext()) && "Cannot have void typed arguments!"); ArgumentList.push_back(new Argument(FT->getParamType(i))); } @@ -242,18 +241,18 @@ static StringPool *GCNamePool; static ManagedStatic<sys::SmartRWMutex<true> > GCLock; bool Function::hasGC() const { - sys::SmartScopedReader<true> Reader(&*GCLock); + sys::SmartScopedReader<true> Reader(*GCLock); return GCNames && GCNames->count(this); } const char *Function::getGC() const { assert(hasGC() && "Function has no collector"); - sys::SmartScopedReader<true> Reader(&*GCLock); + sys::SmartScopedReader<true> Reader(*GCLock); return *(*GCNames)[this]; } void Function::setGC(const char *Str) { - sys::SmartScopedWriter<true> Writer(&*GCLock); + sys::SmartScopedWriter<true> Writer(*GCLock); if (!GCNamePool) GCNamePool = new StringPool(); if (!GCNames) @@ -262,7 +261,7 @@ void Function::setGC(const char *Str) { } void Function::clearGC() { - sys::SmartScopedWriter<true> Writer(&*GCLock); + sys::SmartScopedWriter<true> Writer(*GCLock); if (GCNames) { GCNames->erase(this); if (GCNames->empty()) { @@ -328,15 +327,16 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { for (unsigned i = 0; i < numTys; ++i) { if (const PointerType* PTyp = dyn_cast<PointerType>(Tys[i])) { Result += ".p" + llvm::utostr(PTyp->getAddressSpace()) + - MVT::getMVT(PTyp->getElementType()).getMVTString(); + EVT::getEVT(PTyp->getElementType()).getEVTString(); } else if (Tys[i]) - Result += "." + MVT::getMVT(Tys[i]).getMVTString(); + Result += "." + EVT::getEVT(Tys[i]).getEVTString(); } return Result; } -const FunctionType *Intrinsic::getType(ID id, const Type **Tys, +const FunctionType *Intrinsic::getType(LLVMContext &Context, + ID id, const Type **Tys, unsigned numTys) { const Type *ResultTy = NULL; std::vector<const Type*> ArgTys; @@ -370,7 +370,8 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, // because intrinsics must be a specific type. return cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys), - getType(id, Tys, numTys))); + getType(M->getContext(), + id, Tys, numTys))); } // This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method. diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index 5abe1f9ac40d..d18a20162dd9 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -16,8 +16,10 @@ #include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -76,8 +78,7 @@ void GlobalValue::removeDeadConstantUsers() const { /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { - assert(0 && "You can't GV->destroyConstant()!"); - abort(); + llvm_unreachable("You can't GV->destroyConstant()!"); } /// copyAttributesFrom - copy all additional attributes (those not needed to @@ -93,11 +94,12 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { // GlobalVariable Implementation //===----------------------------------------------------------------------===// -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, const std::string &Name, - Module *ParentModule, bool ThreadLocal, - unsigned AddressSpace) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, +GlobalVariable::GlobalVariable(LLVMContext &Context, const Type *Ty, + bool constant, LinkageTypes Link, + Constant *InitVal, const Twine &Name, + bool ThreadLocal, unsigned AddressSpace) + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, OperandTraits<GlobalVariable>::op_begin(this), InitVal != 0, Link, Name), isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) { @@ -108,16 +110,15 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, } LeakDetector::addGarbageObject(this); - - if (ParentModule) - ParentModule->getGlobalList().push_back(this); } -GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, - Constant *InitVal, const std::string &Name, +GlobalVariable::GlobalVariable(Module &M, const Type *Ty, bool constant, + LinkageTypes Link, Constant *InitVal, + const Twine &Name, GlobalVariable *Before, bool ThreadLocal, unsigned AddressSpace) - : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalVariableVal, + : GlobalValue(PointerType::get(Ty, AddressSpace), + Value::GlobalVariableVal, OperandTraits<GlobalVariable>::op_begin(this), InitVal != 0, Link, Name), isConstantGlobal(constant), isThreadLocalSymbol(ThreadLocal) { @@ -131,6 +132,8 @@ GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link, if (Before) Before->getParent()->getGlobalList().insert(Before, this); + else + M.getGlobalList().push_back(this); } void GlobalVariable::setParent(Module *parent) { @@ -184,7 +187,7 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { //===----------------------------------------------------------------------===// GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link, - const std::string &Name, Constant* aliasee, + const Twine &Name, Constant* aliasee, Module *ParentModule) : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { LeakDetector::addGarbageObject(this); @@ -242,7 +245,7 @@ const GlobalValue *GlobalAlias::getAliasedGlobal() const { CE->getOpcode() == Instruction::GetElementPtr)) return dyn_cast<GlobalValue>(CE->getOperand(0)); else - assert(0 && "Unsupported aliasee"); + llvm_unreachable("Unsupported aliasee"); } } return 0; diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index 524e294ab75f..0520dfa17ced 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -26,18 +26,20 @@ InlineAsm::~InlineAsm() { // NOTE: when memoizing the function type, we have to be careful to handle the // case when the type gets refined. -InlineAsm *InlineAsm::get(const FunctionType *Ty, const std::string &AsmString, - const std::string &Constraints, bool hasSideEffects) { +InlineAsm *InlineAsm::get(const FunctionType *Ty, const StringRef &AsmString, + const StringRef &Constraints, bool hasSideEffects, + bool isMsAsm) { // FIXME: memoize! - return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects); + return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects, isMsAsm); } -InlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString, - const std::string &constraints, bool hasSideEffects) +InlineAsm::InlineAsm(const FunctionType *Ty, const StringRef &asmString, + const StringRef &constraints, bool hasSideEffects, + bool isMsAsm) : Value(PointerType::getUnqual(Ty), Value::InlineAsmVal), AsmString(asmString), - Constraints(constraints), HasSideEffects(hasSideEffects) { + Constraints(constraints), HasSideEffects(hasSideEffects), IsMsAsm(isMsAsm) { // Do various checks on the constraint string and type. assert(Verify(Ty, constraints) && "Function type not legal for constraints!"); @@ -50,9 +52,9 @@ const FunctionType *InlineAsm::getFunctionType() const { /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. -bool InlineAsm::ConstraintInfo::Parse(const std::string &Str, +bool InlineAsm::ConstraintInfo::Parse(const StringRef &Str, std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar) { - std::string::const_iterator I = Str.begin(), E = Str.end(); + StringRef::iterator I = Str.begin(), E = Str.end(); // Initialize Type = isInput; @@ -111,13 +113,13 @@ bool InlineAsm::ConstraintInfo::Parse(const std::string &Str, while (I != E) { if (*I == '{') { // Physical register reference. // Find the end of the register name. - std::string::const_iterator ConstraintEnd = std::find(I+1, E, '}'); + StringRef::iterator ConstraintEnd = std::find(I+1, E, '}'); if (ConstraintEnd == E) return true; // "{foo" Codes.push_back(std::string(I, ConstraintEnd+1)); I = ConstraintEnd+1; } else if (isdigit(*I)) { // Matching Constraint // Maximal munch numbers. - std::string::const_iterator NumStart = I; + StringRef::iterator NumStart = I; while (I != E && isdigit(*I)) ++I; Codes.push_back(std::string(NumStart, I)); @@ -145,16 +147,16 @@ bool InlineAsm::ConstraintInfo::Parse(const std::string &Str, } std::vector<InlineAsm::ConstraintInfo> -InlineAsm::ParseConstraints(const std::string &Constraints) { +InlineAsm::ParseConstraints(const StringRef &Constraints) { std::vector<ConstraintInfo> Result; // Scan the constraints string. - for (std::string::const_iterator I = Constraints.begin(), - E = Constraints.end(); I != E; ) { + for (StringRef::iterator I = Constraints.begin(), + E = Constraints.end(); I != E; ) { ConstraintInfo Info; // Find the end of this constraint. - std::string::const_iterator ConstraintEnd = std::find(I, E, ','); + StringRef::iterator ConstraintEnd = std::find(I, E, ','); if (ConstraintEnd == I || // Empty constraint like ",," Info.Parse(std::string(I, ConstraintEnd), Result)) { @@ -179,7 +181,7 @@ InlineAsm::ParseConstraints(const std::string &Constraints) { /// Verify - Verify that the specified constraint string is reasonable for the /// specified function type, and otherwise validate the constraint string. -bool InlineAsm::Verify(const FunctionType *Ty, const std::string &ConstStr) { +bool InlineAsm::Verify(const FunctionType *Ty, const StringRef &ConstStr) { if (Ty->isVarArg()) return false; std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr); @@ -213,7 +215,7 @@ bool InlineAsm::Verify(const FunctionType *Ty, const std::string &ConstStr) { switch (NumOutputs) { case 0: - if (Ty->getReturnType() != Type::VoidTy) return false; + if (Ty->getReturnType() != Type::getVoidTy(Ty->getContext())) return false; break; case 1: if (isa<StructType>(Ty->getReturnType())) return false; diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index e0764e494b2e..4df536e68b4e 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -11,9 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/Type.h" #include "llvm/Instructions.h" #include "llvm/Function.h" +#include "llvm/Constants.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -47,6 +51,10 @@ Instruction::Instruction(const Type *ty, unsigned it, Use *Ops, unsigned NumOps, // Out of line virtual method, so the vtable, etc has a home. Instruction::~Instruction() { assert(Parent == 0 && "Instruction still linked in the program!"); + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsDeleted(this); + } } @@ -143,8 +151,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { // Other instructions... case ICmp: return "icmp"; case FCmp: return "fcmp"; - case VICmp: return "vicmp"; - case VFCmp: return "vfcmp"; case PHI: return "phi"; case Select: return "select"; case Call: return "call"; @@ -168,6 +174,14 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { /// identical to the current one. This means that all operands match and any /// extra information (e.g. load is volatile) agree. bool Instruction::isIdenticalTo(const Instruction *I) const { + return isIdenticalToWhenDefined(I) && + SubclassOptionalData == I->SubclassOptionalData; +} + +/// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it +/// ignores the SubclassOptionalData flags, which specify conditions +/// under which the instruction's result is undefined. +bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { if (getOpcode() != I->getOpcode() || getNumOperands() != I->getNumOperands() || getType() != I->getType()) @@ -283,11 +297,11 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { return true; continue; } - + if (PN->getIncomingBlock(UI) != BB) return true; } - return false; + return false; } /// mayReadFromMemory - Return true if this instruction may read memory. @@ -367,23 +381,77 @@ bool Instruction::isCommutative(unsigned op) { } } -/// isTrapping - Return true if the instruction may trap. -/// -bool Instruction::isTrapping(unsigned op) { - switch(op) { +// Code here matches isMalloc from MallocHelper, which is not in VMCore. +static bool isMalloc(const Value* I) { + const CallInst *CI = dyn_cast<CallInst>(I); + if (!CI) { + const BitCastInst *BCI = dyn_cast<BitCastInst>(I); + if (!BCI) return false; + + CI = dyn_cast<CallInst>(BCI->getOperand(0)); + } + + if (!CI) return false; + + const Module* M = CI->getParent()->getParent()->getParent(); + Constant *MallocFunc = M->getFunction("malloc"); + + if (CI->getOperand(0) != MallocFunc) + return false; + + return true; +} + +bool Instruction::isSafeToSpeculativelyExecute() const { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (Constant *C = dyn_cast<Constant>(getOperand(i))) + if (C->canTrap()) + return false; + + switch (getOpcode()) { + default: + return true; case UDiv: + case URem: { + // x / y is undefined if y == 0, but calcuations like x / 3 are safe. + ConstantInt *Op = dyn_cast<ConstantInt>(getOperand(1)); + return Op && !Op->isNullValue(); + } case SDiv: - case FDiv: - case URem: - case SRem: - case FRem: - case Load: - case Store: + case SRem: { + // x / y is undefined if y == 0, and might be undefined if y == -1, + // but calcuations like x / 3 are safe. + ConstantInt *Op = dyn_cast<ConstantInt>(getOperand(1)); + return Op && !Op->isNullValue() && !Op->isAllOnesValue(); + } + case Load: { + if (cast<LoadInst>(this)->isVolatile()) + return false; + if (isa<AllocationInst>(getOperand(0)) || isMalloc(getOperand(0))) + return true; + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(getOperand(0))) + return !GV->hasExternalWeakLinkage(); + // FIXME: Handle cases involving GEPs. We have to be careful because + // a load of a out-of-bounds GEP has undefined behavior. + return false; + } case Call: - case Invoke: + return false; // The called function could have undefined behavior or + // side-effects. + // FIXME: We should special-case some intrinsics (bswap, + // overflow-checking arithmetic, etc.) case VAArg: - return true; - default: - return false; + case Alloca: + case Malloc: + case Invoke: + case PHI: + case Store: + case Free: + case Ret: + case Br: + case Switch: + case Unwind: + case Unreachable: + return false; // Misc instructions which have effects } } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 6a6424d39dd2..f3d15cb2b88b 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -12,13 +12,19 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/Operator.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/MathExtras.h" + using namespace llvm; //===----------------------------------------------------------------------===// @@ -43,10 +49,10 @@ CallSite::CallSite(Instruction *C) { I.setPointer(C); I.setInt(isa<CallInst>(C)); } -unsigned CallSite::getCallingConv() const { +CallingConv::ID CallSite::getCallingConv() const { CALLSITE_DELEGATE_GETTER(getCallingConv()); } -void CallSite::setCallingConv(unsigned CC) { +void CallSite::setCallingConv(CallingConv::ID CC) { CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); } const AttrListPtr &CallSite::getAttributes() const { @@ -124,7 +130,7 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) { // Vector select. - if (VT->getElementType() != Type::Int1Ty) + if (VT->getElementType() != Type::getInt1Ty(Op0->getContext())) return "vector select condition element type must be i1"; const VectorType *ET = dyn_cast<VectorType>(Op1->getType()); if (ET == 0) @@ -132,7 +138,7 @@ const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) { if (ET->getNumElements() != VT->getNumElements()) return "vector select requires selected vectors to have " "the same vector length as select condition"; - } else if (Op0->getType() != Type::Int1Ty) { + } else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) { return "select condition must be i1 or <n x i1>"; } return 0; @@ -152,6 +158,7 @@ PHINode::PHINode(const PHINode &PN) OL[i] = PN.getOperand(i); OL[i+1] = PN.getOperand(i+1); } + SubclassOptionalData = PN.SubclassOptionalData; } PHINode::~PHINode() { @@ -223,13 +230,17 @@ void PHINode::resizeOperands(unsigned NumOps) { /// hasConstantValue - If the specified PHI node always merges together the same /// value, return the value, otherwise return null. /// -Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { - // If the PHI node only has one incoming value, eliminate the PHI node... +/// If the PHI has undef operands, but all the rest of the operands are +/// some unique value, return that value if it can be proved that the +/// value dominates the PHI. If DT is null, use a conservative check, +/// otherwise use DT to test for dominance. +/// +Value *PHINode::hasConstantValue(DominatorTree *DT) const { + // If the PHI node only has one incoming value, eliminate the PHI node. if (getNumIncomingValues() == 1) { if (getIncomingValue(0) != this) // not X = phi X return getIncomingValue(0); - else - return UndefValue::get(getType()); // Self cycle is dead. + return UndefValue::get(getType()); // Self cycle is dead. } // Otherwise if all of the incoming values are the same for the PHI, replace @@ -243,8 +254,7 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { } else if (getIncomingValue(i) != this) { // Not the PHI node itself... if (InVal && getIncomingValue(i) != InVal) return 0; // Not the same, bail out. - else - InVal = getIncomingValue(i); + InVal = getIncomingValue(i); } // The only case that could cause InVal to be null is if we have a PHI node @@ -257,12 +267,20 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { // instruction, we cannot always return X as the result of the PHI node. Only // do this if X is not an instruction (thus it must dominate the PHI block), // or if the client is prepared to deal with this possibility. - if (HasUndefInput && !AllowNonDominatingInstruction) - if (Instruction *IV = dyn_cast<Instruction>(InVal)) - // If it's in the entry block, it dominates everything. - if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() || - isa<InvokeInst>(IV)) - return 0; // Cannot guarantee that InVal dominates this PHINode. + if (!HasUndefInput || !isa<Instruction>(InVal)) + return InVal; + + Instruction *IV = cast<Instruction>(InVal); + if (DT) { + // We have a DominatorTree. Do a precise test. + if (!DT->dominates(IV, this)) + return 0; + } else { + // If it is in the entry block, it obviously dominates everything. + if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() || + isa<InvokeInst>(IV)) + return 0; // Cannot guarantee that InVal dominates this PHINode. + } // All of the incoming values are the same, return the value now. return InVal; @@ -348,7 +366,7 @@ void CallInst::init(Value *Func) { assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); } -CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, +CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name, Instruction *InsertBefore) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), @@ -359,7 +377,7 @@ CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, setName(Name); } -CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, +CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), @@ -369,7 +387,7 @@ CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name, init(Func, Actual); setName(Name); } -CallInst::CallInst(Value *Func, const std::string &Name, +CallInst::CallInst(Value *Func, const Twine &Name, Instruction *InsertBefore) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), @@ -380,7 +398,7 @@ CallInst::CallInst(Value *Func, const std::string &Name, setName(Name); } -CallInst::CallInst(Value *Func, const std::string &Name, +CallInst::CallInst(Value *Func, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) ->getElementType())->getReturnType(), @@ -401,6 +419,7 @@ CallInst::CallInst(const CallInst &CI) Use *InOL = CI.OperandList; for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) OL[i] = InOL[i]; + SubclassOptionalData = CI.SubclassOptionalData; } void CallInst::addAttribute(unsigned i, Attributes attr) { @@ -423,6 +442,111 @@ bool CallInst::paramHasAttr(unsigned i, Attributes attr) const { return false; } +/// IsConstantOne - Return true only if val is constant int 1 +static bool IsConstantOne(Value *val) { + assert(val && "IsConstantOne does not work with NULL val"); + return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne(); +} + +static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) { + if (!Amt) + Amt = ConstantInt::get(IntPtrTy, 1); + else { + assert(!isa<BasicBlock>(Amt) && + "Passed basic block into malloc size parameter! Use other ctor"); + assert(Amt->getType() == IntPtrTy && + "Malloc array size is not an intptr!"); + } + return Amt; +} + +static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, + const Type *IntPtrTy, const Type *AllocTy, + Value *ArraySize, const Twine &NameStr) { + assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && + "createMalloc needs either InsertBefore or InsertAtEnd"); + + // malloc(type) becomes: + // bitcast (i8* malloc(typeSize)) to type* + // malloc(type, arraySize) becomes: + // bitcast (i8 *malloc(typeSize*arraySize)) to type* + Value *AllocSize = ConstantExpr::getSizeOf(AllocTy); + AllocSize = ConstantExpr::getTruncOrBitCast(cast<Constant>(AllocSize), + IntPtrTy); + ArraySize = checkArraySize(ArraySize, IntPtrTy); + + if (!IsConstantOne(ArraySize)) { + if (IsConstantOne(AllocSize)) { + AllocSize = ArraySize; // Operand * 1 = Operand + } else if (Constant *CO = dyn_cast<Constant>(ArraySize)) { + Constant *Scale = ConstantExpr::getIntegerCast(CO, IntPtrTy, + false /*ZExt*/); + // Malloc arg is constant product of type size and array size + AllocSize = ConstantExpr::getMul(Scale, cast<Constant>(AllocSize)); + } else { + // Multiply type size by the array size... + if (InsertBefore) + AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, + "mallocsize", InsertBefore); + else + AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, + "mallocsize", InsertAtEnd); + } + } + + assert(AllocSize->getType() == IntPtrTy && "malloc arg is wrong size"); + // Create the call to Malloc. + BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; + Module* M = BB->getParent()->getParent(); + const Type *BPTy = Type::getInt8PtrTy(BB->getContext()); + // prototype malloc as "void *malloc(size_t)" + Constant *MallocF = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL); + if (!cast<Function>(MallocF)->doesNotAlias(0)) + cast<Function>(MallocF)->setDoesNotAlias(0); + const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); + CallInst *MCall = NULL; + Value *MCast = NULL; + if (InsertBefore) { + MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertBefore); + // Create a cast instruction to convert to the right type... + MCast = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore); + } else { + MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertAtEnd); + // Create a cast instruction to convert to the right type... + MCast = new BitCastInst(MCall, AllocPtrType, NameStr); + } + MCall->setTailCall(); + assert(MCall->getType() != Type::getVoidTy(BB->getContext()) && + "Malloc has void return type"); + + return MCast; +} + +/// CreateMalloc - Generate the IR for a call to malloc: +/// 1. Compute the malloc call's argument as the specified type's size, +/// possibly multiplied by the array size if the array size is not +/// constant 1. +/// 2. Call malloc with that argument. +/// 3. Bitcast the result of the malloc call to the specified type. +Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy, + const Type *AllocTy, Value *ArraySize, + const Twine &Name) { + return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, ArraySize, Name); +} + +/// CreateMalloc - Generate the IR for a call to malloc: +/// 1. Compute the malloc call's argument as the specified type's size, +/// possibly multiplied by the array size if the array size is not +/// constant 1. +/// 2. Call malloc with that argument. +/// 3. Bitcast the result of the malloc call to the specified type. +/// Note: This function does not add the bitcast to the basic block, that is the +/// responsibility of the caller. +Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy, + const Type *AllocTy, Value *ArraySize, + const Twine &Name) { + return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, ArraySize, Name); +} //===----------------------------------------------------------------------===// // InvokeInst Implementation @@ -462,6 +586,7 @@ InvokeInst::InvokeInst(const InvokeInst &II) Use *OL = OperandList, *InOL = II.OperandList; for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i) OL[i] = InOL[i]; + SubclassOptionalData = II.SubclassOptionalData; } BasicBlock *InvokeInst::getSuccessorV(unsigned idx) const { @@ -500,30 +625,31 @@ void InvokeInst::removeAttribute(unsigned i, Attributes attr) { //===----------------------------------------------------------------------===// ReturnInst::ReturnInst(const ReturnInst &RI) - : TerminatorInst(Type::VoidTy, Instruction::Ret, + : TerminatorInst(Type::getVoidTy(RI.getContext()), Instruction::Ret, OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(), RI.getNumOperands()) { if (RI.getNumOperands()) Op<0>() = RI.Op<0>(); + SubclassOptionalData = RI.SubclassOptionalData; } -ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Ret, +ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(C), Instruction::Ret, OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal, InsertBefore) { if (retVal) Op<0>() = retVal; } -ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Ret, +ReturnInst::ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(C), Instruction::Ret, OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal, InsertAtEnd) { if (retVal) Op<0>() = retVal; } -ReturnInst::ReturnInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Ret, +ReturnInst::ReturnInst(LLVMContext &Context, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(Context), Instruction::Ret, OperandTraits<ReturnInst>::op_end(this), 0, InsertAtEnd) { } @@ -534,12 +660,11 @@ unsigned ReturnInst::getNumSuccessorsV() const { /// Out-of-line ReturnInst method, put here so the C++ compiler can choose to /// emit the vtable for the class in this translation unit. void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - assert(0 && "ReturnInst has no successors!"); + llvm_unreachable("ReturnInst has no successors!"); } BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const { - assert(0 && "ReturnInst has no successors!"); - abort(); + llvm_unreachable("ReturnInst has no successors!"); return 0; } @@ -550,11 +675,13 @@ ReturnInst::~ReturnInst() { // UnwindInst Implementation //===----------------------------------------------------------------------===// -UnwindInst::UnwindInst(Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Unwind, 0, 0, InsertBefore) { +UnwindInst::UnwindInst(LLVMContext &Context, Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, + 0, 0, InsertBefore) { } -UnwindInst::UnwindInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Unwind, 0, 0, InsertAtEnd) { +UnwindInst::UnwindInst(LLVMContext &Context, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, + 0, 0, InsertAtEnd) { } @@ -563,12 +690,11 @@ unsigned UnwindInst::getNumSuccessorsV() const { } void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - assert(0 && "UnwindInst has no successors!"); + llvm_unreachable("UnwindInst has no successors!"); } BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const { - assert(0 && "UnwindInst has no successors!"); - abort(); + llvm_unreachable("UnwindInst has no successors!"); return 0; } @@ -576,11 +702,14 @@ BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const { // UnreachableInst Implementation //===----------------------------------------------------------------------===// -UnreachableInst::UnreachableInst(Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Unreachable, 0, 0, InsertBefore) { +UnreachableInst::UnreachableInst(LLVMContext &Context, + Instruction *InsertBefore) + : TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable, + 0, 0, InsertBefore) { } -UnreachableInst::UnreachableInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Unreachable, 0, 0, InsertAtEnd) { +UnreachableInst::UnreachableInst(LLVMContext &Context, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::getVoidTy(Context), Instruction::Unreachable, + 0, 0, InsertAtEnd) { } unsigned UnreachableInst::getNumSuccessorsV() const { @@ -588,12 +717,11 @@ unsigned UnreachableInst::getNumSuccessorsV() const { } void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - assert(0 && "UnwindInst has no successors!"); + llvm_unreachable("UnwindInst has no successors!"); } BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const { - assert(0 && "UnwindInst has no successors!"); - abort(); + llvm_unreachable("UnwindInst has no successors!"); return 0; } @@ -603,12 +731,12 @@ BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const { void BranchInst::AssertOK() { if (isConditional()) - assert(getCondition()->getType() == Type::Int1Ty && + assert(getCondition()->getType() == Type::getInt1Ty(getContext()) && "May only branch on boolean predicates!"); } BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Br, + : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 1, 1, InsertBefore) { assert(IfTrue != 0 && "Branch destination may not be null!"); @@ -616,7 +744,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore) } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Br, + : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 3, 3, InsertBefore) { Op<-1>() = IfTrue; @@ -628,7 +756,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, } BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Br, + : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 1, 1, InsertAtEnd) { assert(IfTrue != 0 && "Branch destination may not be null!"); @@ -637,7 +765,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Br, + : TerminatorInst(Type::getVoidTy(IfTrue->getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - 3, 3, InsertAtEnd) { Op<-1>() = IfTrue; @@ -650,7 +778,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BranchInst::BranchInst(const BranchInst &BI) : - TerminatorInst(Type::VoidTy, Instruction::Br, + TerminatorInst(Type::getVoidTy(BI.getContext()), Instruction::Br, OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(), BI.getNumOperands()) { Op<-1>() = BI.Op<-1>(); @@ -659,6 +787,7 @@ BranchInst::BranchInst(const BranchInst &BI) : Op<-3>() = BI.Op<-3>(); Op<-2>() = BI.Op<-2>(); } + SubclassOptionalData = BI.SubclassOptionalData; } @@ -701,35 +830,35 @@ void BranchInst::setSuccessorV(unsigned idx, BasicBlock *B) { // AllocationInst Implementation //===----------------------------------------------------------------------===// -static Value *getAISize(Value *Amt) { +static Value *getAISize(LLVMContext &Context, Value *Amt) { if (!Amt) - Amt = ConstantInt::get(Type::Int32Ty, 1); + Amt = ConstantInt::get(Type::getInt32Ty(Context), 1); else { assert(!isa<BasicBlock>(Amt) && "Passed basic block into allocation size parameter! Use other ctor"); - assert(Amt->getType() == Type::Int32Ty && + assert(Amt->getType() == Type::getInt32Ty(Context) && "Malloc/Allocation array size is not a 32-bit integer!"); } return Amt; } AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - unsigned Align, const std::string &Name, + unsigned Align, const Twine &Name, Instruction *InsertBefore) - : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize), - InsertBefore) { + : UnaryInstruction(PointerType::getUnqual(Ty), iTy, + getAISize(Ty->getContext(), ArraySize), InsertBefore) { setAlignment(Align); - assert(Ty != Type::VoidTy && "Cannot allocate void!"); + assert(Ty != Type::getVoidTy(Ty->getContext()) && "Cannot allocate void!"); setName(Name); } AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, - unsigned Align, const std::string &Name, + unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd) - : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize), - InsertAtEnd) { + : UnaryInstruction(PointerType::getUnqual(Ty), iTy, + getAISize(Ty->getContext(), ArraySize), InsertAtEnd) { setAlignment(Align); - assert(Ty != Type::VoidTy && "Cannot allocate void!"); + assert(Ty != Type::getVoidTy(Ty->getContext()) && "Cannot allocate void!"); setName(Name); } @@ -753,11 +882,6 @@ const Type *AllocationInst::getAllocatedType() const { return getType()->getElementType(); } -AllocaInst::AllocaInst(const AllocaInst &AI) - : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0), - Instruction::Alloca, AI.getAlignment()) { -} - /// isStaticAlloca - Return true if this alloca is in the entry block of the /// function and is a constant size. If so, the code generator will fold it /// into the prolog/epilog code, so it is basically free. @@ -770,11 +894,6 @@ bool AllocaInst::isStaticAlloca() const { return Parent == &Parent->getParent()->front(); } -MallocInst::MallocInst(const MallocInst &MI) - : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0), - Instruction::Malloc, MI.getAlignment()) { -} - //===----------------------------------------------------------------------===// // FreeInst Implementation //===----------------------------------------------------------------------===// @@ -785,12 +904,14 @@ void FreeInst::AssertOK() { } FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore) - : UnaryInstruction(Type::VoidTy, Free, Ptr, InsertBefore) { + : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), + Free, Ptr, InsertBefore) { AssertOK(); } FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd) - : UnaryInstruction(Type::VoidTy, Free, Ptr, InsertAtEnd) { + : UnaryInstruction(Type::getVoidTy(Ptr->getContext()), + Free, Ptr, InsertAtEnd) { AssertOK(); } @@ -804,7 +925,7 @@ void LoadInst::AssertOK() { "Ptr must have pointer type."); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) +LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertBef) { setVolatile(false); @@ -813,7 +934,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef) setName(Name); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE) +LoadInst::LoadInst(Value *Ptr, const Twine &Name, BasicBlock *InsertAE) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertAE) { setVolatile(false); @@ -822,7 +943,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE) setName(Name); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, Instruction *InsertBef) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertBef) { @@ -832,7 +953,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, setName(Name); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, unsigned Align, Instruction *InsertBef) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertBef) { @@ -842,7 +963,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, setName(Name); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, unsigned Align, BasicBlock *InsertAE) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertAE) { @@ -852,7 +973,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, setName(Name); } -LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, +LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, BasicBlock *InsertAE) : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), Load, Ptr, InsertAE) { @@ -922,7 +1043,7 @@ void StoreInst::AssertOK() { StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertBefore) { @@ -934,7 +1055,7 @@ StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) } StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertAtEnd) { @@ -947,7 +1068,7 @@ StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd) StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertBefore) { @@ -960,7 +1081,7 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, Instruction *InsertBefore) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertBefore) { @@ -973,7 +1094,7 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertAtEnd) { @@ -986,7 +1107,7 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, BasicBlock *InsertAtEnd) - : Instruction(Type::VoidTy, Store, + : Instruction(Type::getVoidTy(val->getContext()), Store, OperandTraits<StoreInst>::op_begin(this), OperandTraits<StoreInst>::operands(this), InsertAtEnd) { @@ -1011,7 +1132,7 @@ static unsigned retrieveAddrSpace(const Value *Val) { } void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx, - const std::string &Name) { + const Twine &Name) { assert(NumOperands == 1+NumIdx && "NumOperands not initialized?"); Use *OL = OperandList; OL[0] = Ptr; @@ -1022,7 +1143,7 @@ void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx, setName(Name); } -void GetElementPtrInst::init(Value *Ptr, Value *Idx, const std::string &Name) { +void GetElementPtrInst::init(Value *Ptr, Value *Idx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); Use *OL = OperandList; OL[0] = Ptr; @@ -1040,12 +1161,13 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) Use *GEPIOL = GEPI.OperandList; for (unsigned i = 0, E = NumOperands; i != E; ++i) OL[i] = GEPIOL[i]; + SubclassOptionalData = GEPI.SubclassOptionalData; } GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, - const std::string &Name, Instruction *InBe) - : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)), - retrieveAddrSpace(Ptr)), + const Twine &Name, Instruction *InBe) + : Instruction(PointerType::get( + checkType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, 2, InBe) { @@ -1053,9 +1175,10 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, } GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, - const std::string &Name, BasicBlock *IAE) - : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)), - retrieveAddrSpace(Ptr)), + const Twine &Name, BasicBlock *IAE) + : Instruction(PointerType::get( + checkType(getIndexedType(Ptr->getType(),Idx)), + retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, 2, IAE) { @@ -1155,13 +1278,20 @@ bool GetElementPtrInst::hasAllConstantIndices() const { return true; } +void GetElementPtrInst::setIsInBounds(bool B) { + cast<GEPOperator>(this)->setIsInBounds(B); +} + +bool GetElementPtrInst::isInBounds() const { + return cast<GEPOperator>(this)->isInBounds(); +} //===----------------------------------------------------------------------===// // ExtractElementInst Implementation //===----------------------------------------------------------------------===// ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, - const std::string &Name, + const Twine &Name, Instruction *InsertBef) : Instruction(cast<VectorType>(Val->getType())->getElementType(), ExtractElement, @@ -1174,24 +1304,8 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, setName(Name); } -ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV, - const std::string &Name, - Instruction *InsertBef) - : Instruction(cast<VectorType>(Val->getType())->getElementType(), - ExtractElement, - OperandTraits<ExtractElementInst>::op_begin(this), - 2, InsertBef) { - Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV); - assert(isValidOperands(Val, Index) && - "Invalid extractelement instruction operands!"); - Op<0>() = Val; - Op<1>() = Index; - setName(Name); -} - - ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAE) : Instruction(cast<VectorType>(Val->getType())->getElementType(), ExtractElement, @@ -1205,25 +1319,10 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, setName(Name); } -ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV, - const std::string &Name, - BasicBlock *InsertAE) - : Instruction(cast<VectorType>(Val->getType())->getElementType(), - ExtractElement, - OperandTraits<ExtractElementInst>::op_begin(this), - 2, InsertAE) { - Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV); - assert(isValidOperands(Val, Index) && - "Invalid extractelement instruction operands!"); - - Op<0>() = Val; - Op<1>() = Index; - setName(Name); -} - bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) { - if (!isa<VectorType>(Val->getType()) || Index->getType() != Type::Int32Ty) + if (!isa<VectorType>(Val->getType()) || + Index->getType() != Type::getInt32Ty(Val->getContext())) return false; return true; } @@ -1233,15 +1332,8 @@ bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) { // InsertElementInst Implementation //===----------------------------------------------------------------------===// -InsertElementInst::InsertElementInst(const InsertElementInst &IE) - : Instruction(IE.getType(), InsertElement, - OperandTraits<InsertElementInst>::op_begin(this), 3) { - Op<0>() = IE.Op<0>(); - Op<1>() = IE.Op<1>(); - Op<2>() = IE.Op<2>(); -} InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, - const std::string &Name, + const Twine &Name, Instruction *InsertBef) : Instruction(Vec->getType(), InsertElement, OperandTraits<InsertElementInst>::op_begin(this), @@ -1254,24 +1346,8 @@ InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, setName(Name); } -InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV, - const std::string &Name, - Instruction *InsertBef) - : Instruction(Vec->getType(), InsertElement, - OperandTraits<InsertElementInst>::op_begin(this), - 3, InsertBef) { - Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV); - assert(isValidOperands(Vec, Elt, Index) && - "Invalid insertelement instruction operands!"); - Op<0>() = Vec; - Op<1>() = Elt; - Op<2>() = Index; - setName(Name); -} - - InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAE) : Instruction(Vec->getType(), InsertElement, OperandTraits<InsertElementInst>::op_begin(this), @@ -1285,22 +1361,6 @@ InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index, setName(Name); } -InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV, - const std::string &Name, - BasicBlock *InsertAE) -: Instruction(Vec->getType(), InsertElement, - OperandTraits<InsertElementInst>::op_begin(this), - 3, InsertAE) { - Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV); - assert(isValidOperands(Vec, Elt, Index) && - "Invalid insertelement instruction operands!"); - - Op<0>() = Vec; - Op<1>() = Elt; - Op<2>() = Index; - setName(Name); -} - bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, const Value *Index) { if (!isa<VectorType>(Vec->getType())) @@ -1309,7 +1369,7 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType()) return false;// Second operand of insertelement must be vector element type. - if (Index->getType() != Type::Int32Ty) + if (Index->getType() != Type::getInt32Ty(Vec->getContext())) return false; // Third operand of insertelement must be i32. return true; } @@ -1319,17 +1379,8 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, // ShuffleVectorInst Implementation //===----------------------------------------------------------------------===// -ShuffleVectorInst::ShuffleVectorInst(const ShuffleVectorInst &SV) - : Instruction(SV.getType(), ShuffleVector, - OperandTraits<ShuffleVectorInst>::op_begin(this), - OperandTraits<ShuffleVectorInst>::operands(this)) { - Op<0>() = SV.Op<0>(); - Op<1>() = SV.Op<1>(); - Op<2>() = SV.Op<2>(); -} - ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) : Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(), cast<VectorType>(Mask->getType())->getNumElements()), @@ -1346,12 +1397,14 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, } ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) - : Instruction(V1->getType(), ShuffleVector, - OperandTraits<ShuffleVectorInst>::op_begin(this), - OperandTraits<ShuffleVectorInst>::operands(this), - InsertAtEnd) { +: Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(), + cast<VectorType>(Mask->getType())->getNumElements()), + ShuffleVector, + OperandTraits<ShuffleVectorInst>::op_begin(this), + OperandTraits<ShuffleVectorInst>::operands(this), + InsertAtEnd) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); @@ -1368,7 +1421,7 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType()); if (!isa<Constant>(Mask) || MaskTy == 0 || - MaskTy->getElementType() != Type::Int32Ty) + MaskTy->getElementType() != Type::getInt32Ty(V1->getContext())) return false; return true; } @@ -1393,7 +1446,7 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const { //===----------------------------------------------------------------------===// void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, - unsigned NumIdx, const std::string &Name) { + unsigned NumIdx, const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); Op<0>() = Agg; Op<1>() = Val; @@ -1403,7 +1456,7 @@ void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, } void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx, - const std::string &Name) { + const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); Op<0>() = Agg; Op<1>() = Val; @@ -1418,12 +1471,13 @@ InsertValueInst::InsertValueInst(const InsertValueInst &IVI) Indices(IVI.Indices) { Op<0>() = IVI.getOperand(0); Op<1>() = IVI.getOperand(1); + SubclassOptionalData = IVI.SubclassOptionalData; } InsertValueInst::InsertValueInst(Value *Agg, Value *Val, unsigned Idx, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) : Instruction(Agg->getType(), InsertValue, OperandTraits<InsertValueInst>::op_begin(this), @@ -1434,7 +1488,7 @@ InsertValueInst::InsertValueInst(Value *Agg, InsertValueInst::InsertValueInst(Value *Agg, Value *Val, unsigned Idx, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(Agg->getType(), InsertValue, OperandTraits<InsertValueInst>::op_begin(this), @@ -1447,14 +1501,14 @@ InsertValueInst::InsertValueInst(Value *Agg, //===----------------------------------------------------------------------===// void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx, - const std::string &Name) { + const Twine &Name) { assert(NumOperands == 1 && "NumOperands not initialized?"); Indices.insert(Indices.end(), Idx, Idx + NumIdx); setName(Name); } -void ExtractValueInst::init(unsigned Idx, const std::string &Name) { +void ExtractValueInst::init(unsigned Idx, const Twine &Name) { assert(NumOperands == 1 && "NumOperands not initialized?"); Indices.push_back(Idx); @@ -1464,6 +1518,7 @@ void ExtractValueInst::init(unsigned Idx, const std::string &Name) { ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)), Indices(EVI.Indices) { + SubclassOptionalData = EVI.SubclassOptionalData; } // getIndexedType - Returns the type of the element that would be extracted @@ -1517,7 +1572,7 @@ static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType, } BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, - const Type *Ty, const std::string &Name, + const Type *Ty, const Twine &Name, Instruction *InsertBefore) : Instruction(Ty, AdjustIType(iType, Ty), OperandTraits<BinaryOperator>::op_begin(this), @@ -1530,7 +1585,7 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, } BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, - const Type *Ty, const std::string &Name, + const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(Ty, AdjustIType(iType, Ty), OperandTraits<BinaryOperator>::op_begin(this), @@ -1619,7 +1674,7 @@ void BinaryOperator::init(BinaryOps iType) { } BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { assert(S1->getType() == S2->getType() && "Cannot create binary operator with two operands of differing type!"); @@ -1627,69 +1682,70 @@ BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, } BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { BinaryOperator *Res = Create(Op, S1, S2, Name); InsertAtEnd->getInstList().push_back(Res); return Res; } -BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { - Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::Sub, zero, Op, Op->getType(), Name, InsertBefore); } -BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { - Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::Sub, zero, Op, Op->getType(), Name, InsertAtEnd); } -BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, Instruction *InsertBefore) { - Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertBefore); } -BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { - Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + Value *zero = ConstantFP::getZeroValueForNegation(Op->getType()); return new BinaryOperator(Instruction::FSub, zero, Op, Op->getType(), Name, InsertAtEnd); } -BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, Instruction *InsertBefore) { Constant *C; if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) { - C = ConstantInt::getAllOnesValue(PTy->getElementType()); - C = ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), C)); + C = Constant::getAllOnesValue(PTy->getElementType()); + C = ConstantVector::get( + std::vector<Constant*>(PTy->getNumElements(), C)); } else { - C = ConstantInt::getAllOnesValue(Op->getType()); + C = Constant::getAllOnesValue(Op->getType()); } return new BinaryOperator(Instruction::Xor, Op, C, Op->getType(), Name, InsertBefore); } -BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name, +BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd) { Constant *AllOnes; if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) { // Create a vector of all ones values. - Constant *Elt = ConstantInt::getAllOnesValue(PTy->getElementType()); - AllOnes = - ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), Elt)); + Constant *Elt = Constant::getAllOnesValue(PTy->getElementType()); + AllOnes = ConstantVector::get( + std::vector<Constant*>(PTy->getNumElements(), Elt)); } else { - AllOnes = ConstantInt::getAllOnesValue(Op->getType()); + AllOnes = Constant::getAllOnesValue(Op->getType()); } return new BinaryOperator(Instruction::Xor, Op, AllOnes, @@ -1709,16 +1765,16 @@ static inline bool isConstantAllOnes(const Value *V) { bool BinaryOperator::isNeg(const Value *V) { if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V)) if (Bop->getOpcode() == Instruction::Sub) - return Bop->getOperand(0) == - ConstantExpr::getZeroValueForNegationExpr(Bop->getType()); + if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0))) + return C->isNegativeZeroValue(); return false; } bool BinaryOperator::isFNeg(const Value *V) { if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V)) if (Bop->getOpcode() == Instruction::FSub) - return Bop->getOperand(0) == - ConstantExpr::getZeroValueForNegationExpr(Bop->getType()); + if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0))) + return C->isNegativeZeroValue(); return false; } @@ -1731,7 +1787,6 @@ bool BinaryOperator::isNot(const Value *V) { } Value *BinaryOperator::getNegArgument(Value *BinOp) { - assert(isNeg(BinOp) && "getNegArgument from non-'neg' instruction!"); return cast<BinaryOperator>(BinOp)->getOperand(1); } @@ -1740,7 +1795,6 @@ const Value *BinaryOperator::getNegArgument(const Value *BinOp) { } Value *BinaryOperator::getFNegArgument(Value *BinOp) { - assert(isFNeg(BinOp) && "getFNegArgument from non-'fneg' instruction!"); return cast<BinaryOperator>(BinOp)->getOperand(1); } @@ -1776,6 +1830,30 @@ bool BinaryOperator::swapOperands() { return false; } +void BinaryOperator::setHasNoUnsignedWrap(bool b) { + cast<OverflowingBinaryOperator>(this)->setHasNoUnsignedWrap(b); +} + +void BinaryOperator::setHasNoSignedWrap(bool b) { + cast<OverflowingBinaryOperator>(this)->setHasNoSignedWrap(b); +} + +void BinaryOperator::setIsExact(bool b) { + cast<SDivOperator>(this)->setIsExact(b); +} + +bool BinaryOperator::hasNoUnsignedWrap() const { + return cast<OverflowingBinaryOperator>(this)->hasNoUnsignedWrap(); +} + +bool BinaryOperator::hasNoSignedWrap() const { + return cast<OverflowingBinaryOperator>(this)->hasNoSignedWrap(); +} + +bool BinaryOperator::isExact() const { + return cast<SDivOperator>(this)->isExact(); +} + //===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// @@ -1944,6 +2022,8 @@ unsigned CastInst::isEliminableCastPair( return 0; case 7: { // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size + if (!IntPtrTy) + return 0; unsigned PtrSize = IntPtrTy->getScalarSizeInBits(); unsigned MidSize = MidTy->getScalarSizeInBits(); if (MidSize >= PtrSize) @@ -1983,6 +2063,8 @@ unsigned CastInst::isEliminableCastPair( return 0; case 13: { // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize + if (!IntPtrTy) + return 0; unsigned PtrSize = IntPtrTy->getScalarSizeInBits(); unsigned SrcSize = SrcTy->getScalarSizeInBits(); unsigned DstSize = DstTy->getScalarSizeInBits(); @@ -2003,7 +2085,7 @@ unsigned CastInst::isEliminableCastPair( } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, - const std::string &Name, Instruction *InsertBefore) { + const Twine &Name, Instruction *InsertBefore) { // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertBefore); @@ -2025,7 +2107,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, } CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, - const std::string &Name, BasicBlock *InsertAtEnd) { + const Twine &Name, BasicBlock *InsertAtEnd) { // Construct and return the appropriate CastInst subclass switch (op) { case Trunc: return new TruncInst (S, Ty, Name, InsertAtEnd); @@ -2047,7 +2129,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, } CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); @@ -2055,7 +2137,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); @@ -2063,7 +2145,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); @@ -2071,7 +2153,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); @@ -2079,7 +2161,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertBefore); @@ -2087,7 +2169,7 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits()) return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd); @@ -2095,7 +2177,7 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty, } CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { assert(isa<PointerType>(S->getType()) && "Invalid cast"); assert((Ty->isInteger() || isa<PointerType>(Ty)) && @@ -2108,7 +2190,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty, /// @brief Create a BitCast or a PtrToInt cast instruction CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { assert(isa<PointerType>(S->getType()) && "Invalid cast"); assert((Ty->isInteger() || isa<PointerType>(Ty)) && @@ -2120,7 +2202,7 @@ CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty, } CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, - bool isSigned, const std::string &Name, + bool isSigned, const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast"); unsigned SrcBits = C->getType()->getScalarSizeInBits(); @@ -2133,7 +2215,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, } CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, - bool isSigned, const std::string &Name, + bool isSigned, const Twine &Name, BasicBlock *InsertAtEnd) { assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() && "Invalid cast"); @@ -2147,7 +2229,7 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, } CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, - const std::string &Name, + const Twine &Name, Instruction *InsertBefore) { assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && "Invalid cast"); @@ -2160,7 +2242,7 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, } CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, - const std::string &Name, + const Twine &Name, BasicBlock *InsertAtEnd) { assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() && "Invalid cast"); @@ -2295,7 +2377,7 @@ CastInst::getCastOpcode( PTy = NULL; return BitCast; // same size, no-op cast } else { - assert(0 && "Casting pointer or non-first class to float"); + llvm_unreachable("Casting pointer or non-first class to float"); } } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) { if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) { @@ -2404,144 +2486,144 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) { } TruncInst::TruncInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, Trunc, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); } TruncInst::TruncInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, Trunc, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc"); } ZExtInst::ZExtInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, ZExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } ZExtInst::ZExtInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt"); } SExtInst::SExtInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } SExtInst::SExtInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, SExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt"); } FPTruncInst::FPTruncInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } FPTruncInst::FPTruncInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc"); } FPExtInst::FPExtInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPExt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } FPExtInst::FPExtInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt"); } UIToFPInst::UIToFPInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } UIToFPInst::UIToFPInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP"); } SIToFPInst::SIToFPInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } SIToFPInst::SIToFPInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, SIToFP, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP"); } FPToUIInst::FPToUIInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } FPToUIInst::FPToUIInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPToUI, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI"); } FPToSIInst::FPToSIInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } FPToSIInst::FPToSIInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, FPToSI, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI"); } PtrToIntInst::PtrToIntInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } PtrToIntInst::PtrToIntInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, PtrToInt, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt"); } IntToPtrInst::IntToPtrInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); } IntToPtrInst::IntToPtrInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, IntToPtr, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr"); } BitCastInst::BitCastInst( - Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore + Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore ) : CastInst(Ty, BitCast, S, Name, InsertBefore) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } BitCastInst::BitCastInst( - Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd + Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd ) : CastInst(Ty, BitCast, S, Name, InsertAtEnd) { assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast"); } @@ -2551,7 +2633,7 @@ BitCastInst::BitCastInst( //===----------------------------------------------------------------------===// CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, - Value *LHS, Value *RHS, const std::string &Name, + Value *LHS, Value *RHS, const Twine &Name, Instruction *InsertBefore) : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this), @@ -2564,7 +2646,7 @@ CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, } CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, - Value *LHS, Value *RHS, const std::string &Name, + Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd) : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this), @@ -2577,41 +2659,35 @@ CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate, } CmpInst * -CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, - const std::string &Name, Instruction *InsertBefore) { +CmpInst::Create(OtherOps Op, unsigned short predicate, + Value *S1, Value *S2, + const Twine &Name, Instruction *InsertBefore) { if (Op == Instruction::ICmp) { - return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertBefore); - } - if (Op == Instruction::FCmp) { - return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertBefore); - } - if (Op == Instruction::VICmp) { - return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertBefore); + if (InsertBefore) + return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate), + S1, S2, Name); + else + return new ICmpInst(CmpInst::Predicate(predicate), + S1, S2, Name); } - return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertBefore); + + if (InsertBefore) + return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate), + S1, S2, Name); + else + return new FCmpInst(CmpInst::Predicate(predicate), + S1, S2, Name); } CmpInst * CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, - const std::string &Name, BasicBlock *InsertAtEnd) { + const Twine &Name, BasicBlock *InsertAtEnd) { if (Op == Instruction::ICmp) { - return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertAtEnd); - } - if (Op == Instruction::FCmp) { - return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertAtEnd); + return new ICmpInst(*InsertAtEnd, CmpInst::Predicate(predicate), + S1, S2, Name); } - if (Op == Instruction::VICmp) { - return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertAtEnd); - } - return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name, - InsertAtEnd); + return new FCmpInst(*InsertAtEnd, CmpInst::Predicate(predicate), + S1, S2, Name); } void CmpInst::swapOperands() { @@ -2712,7 +2788,7 @@ ICmpInst::makeConstantRange(Predicate pred, const APInt &C) { APInt Upper(C); uint32_t BitWidth = C.getBitWidth(); switch (pred) { - default: assert(0 && "Invalid ICmp opcode to ConstantRange ctor!"); + default: llvm_unreachable("Invalid ICmp opcode to ConstantRange ctor!"); case ICmpInst::ICMP_EQ: Upper++; break; case ICmpInst::ICMP_NE: Lower++; break; case ICmpInst::ICMP_ULT: Lower = APInt::getMinValue(BitWidth); break; @@ -2823,7 +2899,8 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) { /// constructor can also autoinsert before another instruction. SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Switch, 0, 0, InsertBefore) { + : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, + 0, 0, InsertBefore) { init(Value, Default, NumCases); } @@ -2833,18 +2910,20 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Switch, 0, 0, InsertAtEnd) { + : TerminatorInst(Type::getVoidTy(Value->getContext()), Instruction::Switch, + 0, 0, InsertAtEnd) { init(Value, Default, NumCases); } SwitchInst::SwitchInst(const SwitchInst &SI) - : TerminatorInst(Type::VoidTy, Instruction::Switch, + : TerminatorInst(Type::getVoidTy(SI.getContext()), Instruction::Switch, allocHungoffUses(SI.getNumOperands()), SI.getNumOperands()) { Use *OL = OperandList, *InOL = SI.OperandList; for (unsigned i = 0, E = SI.getNumOperands(); i != E; i+=2) { OL[i] = InOL[i]; OL[i+1] = InOL[i+1]; } + SubclassOptionalData = SI.SubclassOptionalData; } SwitchInst::~SwitchInst() { @@ -2937,80 +3016,372 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) { // unit that uses these classes. GetElementPtrInst *GetElementPtrInst::clone() const { - return new(getNumOperands()) GetElementPtrInst(*this); + GetElementPtrInst *New = new(getNumOperands()) GetElementPtrInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } BinaryOperator *BinaryOperator::clone() const { - return Create(getOpcode(), Op<0>(), Op<1>()); + BinaryOperator *New = Create(getOpcode(), Op<0>(), Op<1>()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } FCmpInst* FCmpInst::clone() const { - return new FCmpInst(getPredicate(), Op<0>(), Op<1>()); + FCmpInst *New = new FCmpInst(getPredicate(), Op<0>(), Op<1>()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } ICmpInst* ICmpInst::clone() const { - return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); + ICmpInst *New = new ICmpInst(getPredicate(), Op<0>(), Op<1>()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -VFCmpInst* VFCmpInst::clone() const { - return new VFCmpInst(getPredicate(), Op<0>(), Op<1>()); +ExtractValueInst *ExtractValueInst::clone() const { + ExtractValueInst *New = new ExtractValueInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} +InsertValueInst *InsertValueInst::clone() const { + InsertValueInst *New = new InsertValueInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -VICmpInst* VICmpInst::clone() const { - return new VICmpInst(getPredicate(), Op<0>(), Op<1>()); + +MallocInst *MallocInst::clone() const { + MallocInst *New = new MallocInst(getAllocatedType(), + (Value*)getOperand(0), + getAlignment()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -ExtractValueInst *ExtractValueInst::clone() const { - return new ExtractValueInst(*this); +AllocaInst *AllocaInst::clone() const { + AllocaInst *New = new AllocaInst(getAllocatedType(), + (Value*)getOperand(0), + getAlignment()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +FreeInst *FreeInst::clone() const { + FreeInst *New = new FreeInst(getOperand(0)); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +LoadInst *LoadInst::clone() const { + LoadInst *New = new LoadInst(getOperand(0), + Twine(), isVolatile(), + getAlignment()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +StoreInst *StoreInst::clone() const { + StoreInst *New = new StoreInst(getOperand(0), getOperand(1), + isVolatile(), getAlignment()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +TruncInst *TruncInst::clone() const { + TruncInst *New = new TruncInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +ZExtInst *ZExtInst::clone() const { + ZExtInst *New = new ZExtInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +SExtInst *SExtInst::clone() const { + SExtInst *New = new SExtInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +FPTruncInst *FPTruncInst::clone() const { + FPTruncInst *New = new FPTruncInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +FPExtInst *FPExtInst::clone() const { + FPExtInst *New = new FPExtInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +UIToFPInst *UIToFPInst::clone() const { + UIToFPInst *New = new UIToFPInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +SIToFPInst *SIToFPInst::clone() const { + SIToFPInst *New = new SIToFPInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +FPToUIInst *FPToUIInst::clone() const { + FPToUIInst *New = new FPToUIInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +FPToSIInst *FPToSIInst::clone() const { + FPToSIInst *New = new FPToSIInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +PtrToIntInst *PtrToIntInst::clone() const { + PtrToIntInst *New = new PtrToIntInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +IntToPtrInst *IntToPtrInst::clone() const { + IntToPtrInst *New = new IntToPtrInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +BitCastInst *BitCastInst::clone() const { + BitCastInst *New = new BitCastInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +CallInst *CallInst::clone() const { + CallInst *New = new(getNumOperands()) CallInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +SelectInst *SelectInst::clone() const { + SelectInst *New = SelectInst::Create(getOperand(0), + getOperand(1), + getOperand(2)); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +VAArgInst *VAArgInst::clone() const { + VAArgInst *New = new VAArgInst(getOperand(0), getType()); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -InsertValueInst *InsertValueInst::clone() const { - return new InsertValueInst(*this); -} - - -MallocInst *MallocInst::clone() const { return new MallocInst(*this); } -AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } -FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } -LoadInst *LoadInst::clone() const { return new LoadInst(*this); } -StoreInst *StoreInst::clone() const { return new StoreInst(*this); } -CastInst *TruncInst::clone() const { return new TruncInst(*this); } -CastInst *ZExtInst::clone() const { return new ZExtInst(*this); } -CastInst *SExtInst::clone() const { return new SExtInst(*this); } -CastInst *FPTruncInst::clone() const { return new FPTruncInst(*this); } -CastInst *FPExtInst::clone() const { return new FPExtInst(*this); } -CastInst *UIToFPInst::clone() const { return new UIToFPInst(*this); } -CastInst *SIToFPInst::clone() const { return new SIToFPInst(*this); } -CastInst *FPToUIInst::clone() const { return new FPToUIInst(*this); } -CastInst *FPToSIInst::clone() const { return new FPToSIInst(*this); } -CastInst *PtrToIntInst::clone() const { return new PtrToIntInst(*this); } -CastInst *IntToPtrInst::clone() const { return new IntToPtrInst(*this); } -CastInst *BitCastInst::clone() const { return new BitCastInst(*this); } -CallInst *CallInst::clone() const { - return new(getNumOperands()) CallInst(*this); -} -SelectInst *SelectInst::clone() const { - return new(getNumOperands()) SelectInst(*this); -} -VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); } ExtractElementInst *ExtractElementInst::clone() const { - return new ExtractElementInst(*this); + ExtractElementInst *New = ExtractElementInst::Create(getOperand(0), + getOperand(1)); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } + InsertElementInst *InsertElementInst::clone() const { - return InsertElementInst::Create(*this); + InsertElementInst *New = InsertElementInst::Create(getOperand(0), + getOperand(1), + getOperand(2)); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } + ShuffleVectorInst *ShuffleVectorInst::clone() const { - return new ShuffleVectorInst(*this); + ShuffleVectorInst *New = new ShuffleVectorInst(getOperand(0), + getOperand(1), + getOperand(2)); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +PHINode *PHINode::clone() const { + PHINode *New = new PHINode(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -PHINode *PHINode::clone() const { return new PHINode(*this); } + ReturnInst *ReturnInst::clone() const { - return new(getNumOperands()) ReturnInst(*this); + ReturnInst *New = new(getNumOperands()) ReturnInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } + BranchInst *BranchInst::clone() const { unsigned Ops(getNumOperands()); - return new(Ops, Ops == 1) BranchInst(*this); + BranchInst *New = new(Ops, Ops == 1) BranchInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +SwitchInst *SwitchInst::clone() const { + SwitchInst *New = new SwitchInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; } -SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); } + InvokeInst *InvokeInst::clone() const { - return new(getNumOperands()) InvokeInst(*this); + InvokeInst *New = new(getNumOperands()) InvokeInst(*this); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + } + return New; +} + +UnwindInst *UnwindInst::clone() const { + LLVMContext &Context = getContext(); + UnwindInst *New = new UnwindInst(Context); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + return New; +} + +UnreachableInst *UnreachableInst::clone() const { + LLVMContext &Context = getContext(); + UnreachableInst *New = new UnreachableInst(Context); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) + Context.pImpl->TheMetadata.ValueIsCloned(this, New); + return New; } -UnwindInst *UnwindInst::clone() const { return new UnwindInst(); } -UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();} diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp index 8bdc96896c51..5f33d0eebb94 100644 --- a/lib/VMCore/IntrinsicInst.cpp +++ b/lib/VMCore/IntrinsicInst.cpp @@ -61,17 +61,11 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) { Value *DbgStopPointInst::getFileName() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (7 << 16) && "Verify operand indices"); - GlobalVariable *GV = cast<GlobalVariable>(getContext()); - if (!GV->hasInitializer()) return NULL; - ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(3); + return getContext()->getElement(3); } Value *DbgStopPointInst::getDirectory() const { // Once the operand indices are verified, update this assert assert(LLVMDebugVersion == (7 << 16) && "Verify operand indices"); - GlobalVariable *GV = cast<GlobalVariable>(getContext()); - if (!GV->hasInitializer()) return NULL; - ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer()); - return CS->getOperand(4); + return getContext()->getElement(4); } diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index fe2cb7bf196f..39ed7ed68828 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -8,16 +8,18 @@ //===----------------------------------------------------------------------===// // // This file implements LLVMContext, as a wrapper around the opaque -// class LLVMContextImpl. +// class LLVMContextImpl. // //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" #include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/MDNode.h" +#include "llvm/Instruction.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/ValueHandle.h" #include "LLVMContextImpl.h" +#include <set> using namespace llvm; @@ -27,463 +29,48 @@ LLVMContext& llvm::getGlobalContext() { return *GlobalContext; } -LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl()) { } +LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { } LLVMContext::~LLVMContext() { delete pImpl; } -// Constant accessors -Constant* LLVMContext::getNullValue(const Type* Ty) { - return Constant::getNullValue(Ty); -} - -Constant* LLVMContext::getAllOnesValue(const Type* Ty) { - return Constant::getAllOnesValue(Ty); -} - -// UndefValue accessors. -UndefValue* LLVMContext::getUndef(const Type* Ty) { - return UndefValue::get(Ty); -} - -// ConstantInt accessors. -ConstantInt* LLVMContext::getConstantIntTrue() { - return ConstantInt::getTrue(); -} - -ConstantInt* LLVMContext::getConstantIntFalse() { - return ConstantInt::getFalse(); -} - -Constant* LLVMContext::getConstantInt(const Type* Ty, uint64_t V, - bool isSigned) { - return ConstantInt::get(Ty, V, isSigned); -} - - -ConstantInt* LLVMContext::getConstantInt(const IntegerType* Ty, uint64_t V, - bool isSigned) { - return ConstantInt::get(Ty, V, isSigned); -} - -ConstantInt* LLVMContext::getConstantIntSigned(const IntegerType* Ty, - int64_t V) { - return ConstantInt::getSigned(Ty, V); -} - -ConstantInt* LLVMContext::getConstantInt(const APInt& V) { - return ConstantInt::get(V); -} - -Constant* LLVMContext::getConstantInt(const Type* Ty, const APInt& V) { - return ConstantInt::get(Ty, V); -} - -ConstantInt* LLVMContext::getConstantIntAllOnesValue(const Type* Ty) { - return ConstantInt::getAllOnesValue(Ty); -} - - -// ConstantPointerNull accessors. -ConstantPointerNull* LLVMContext::getConstantPointerNull(const PointerType* T) { - return ConstantPointerNull::get(T); -} - - -// ConstantStruct accessors. -Constant* LLVMContext::getConstantStruct(const StructType* T, - const std::vector<Constant*>& V) { - return ConstantStruct::get(T, V); -} - -Constant* LLVMContext::getConstantStruct(const std::vector<Constant*>& V, - bool Packed) { - return ConstantStruct::get(V, Packed); -} - -Constant* LLVMContext::getConstantStruct(Constant* const *Vals, - unsigned NumVals, bool Packed) { - return ConstantStruct::get(Vals, NumVals, Packed); -} - - -// ConstantAggregateZero accessors. -ConstantAggregateZero* LLVMContext::getConstantAggregateZero(const Type* Ty) { - return ConstantAggregateZero::get(Ty); -} - - -// ConstantArray accessors. -Constant* LLVMContext::getConstantArray(const ArrayType* T, - const std::vector<Constant*>& V) { - return ConstantArray::get(T, V); -} - -Constant* LLVMContext::getConstantArray(const ArrayType* T, - Constant* const* Vals, - unsigned NumVals) { - return ConstantArray::get(T, Vals, NumVals); -} - -Constant* LLVMContext::getConstantArray(const std::string& Initializer, - bool AddNull) { - return ConstantArray::get(Initializer, AddNull); -} - - -// ConstantExpr accessors. -Constant* LLVMContext::getConstantExpr(unsigned Opcode, Constant* C1, - Constant* C2) { - return ConstantExpr::get(Opcode, C1, C2); -} - -Constant* LLVMContext::getConstantExprTrunc(Constant* C, const Type* Ty) { - return ConstantExpr::getTrunc(C, Ty); -} - -Constant* LLVMContext::getConstantExprSExt(Constant* C, const Type* Ty) { - return ConstantExpr::getSExt(C, Ty); -} - -Constant* LLVMContext::getConstantExprZExt(Constant* C, const Type* Ty) { - return ConstantExpr::getZExt(C, Ty); -} - -Constant* LLVMContext::getConstantExprFPTrunc(Constant* C, const Type* Ty) { - return ConstantExpr::getFPTrunc(C, Ty); -} - -Constant* LLVMContext::getConstantExprFPExtend(Constant* C, const Type* Ty) { - return ConstantExpr::getFPExtend(C, Ty); -} - -Constant* LLVMContext::getConstantExprUIToFP(Constant* C, const Type* Ty) { - return ConstantExpr::getUIToFP(C, Ty); -} - -Constant* LLVMContext::getConstantExprSIToFP(Constant* C, const Type* Ty) { - return ConstantExpr::getSIToFP(C, Ty); -} - -Constant* LLVMContext::getConstantExprFPToUI(Constant* C, const Type* Ty) { - return ConstantExpr::getFPToUI(C, Ty); -} - -Constant* LLVMContext::getConstantExprFPToSI(Constant* C, const Type* Ty) { - return ConstantExpr::getFPToSI(C, Ty); -} - -Constant* LLVMContext::getConstantExprPtrToInt(Constant* C, const Type* Ty) { - return ConstantExpr::getPtrToInt(C, Ty); -} - -Constant* LLVMContext::getConstantExprIntToPtr(Constant* C, const Type* Ty) { - return ConstantExpr::getIntToPtr(C, Ty); -} - -Constant* LLVMContext::getConstantExprBitCast(Constant* C, const Type* Ty) { - return ConstantExpr::getBitCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprCast(unsigned ops, Constant* C, - const Type* Ty) { - return ConstantExpr::getCast(ops, C, Ty); -} - -Constant* LLVMContext::getConstantExprZExtOrBitCast(Constant* C, - const Type* Ty) { - return ConstantExpr::getZExtOrBitCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprSExtOrBitCast(Constant* C, - const Type* Ty) { - return ConstantExpr::getSExtOrBitCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprTruncOrBitCast(Constant* C, - const Type* Ty) { - return ConstantExpr::getTruncOrBitCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprPointerCast(Constant* C, const Type* Ty) { - return ConstantExpr::getPointerCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprIntegerCast(Constant* C, const Type* Ty, - bool isSigned) { - return ConstantExpr::getIntegerCast(C, Ty, isSigned); -} - -Constant* LLVMContext::getConstantExprFPCast(Constant* C, const Type* Ty) { - return ConstantExpr::getFPCast(C, Ty); -} - -Constant* LLVMContext::getConstantExprSelect(Constant* C, Constant* V1, - Constant* V2) { - return ConstantExpr::getSelect(C, V1, V2); -} - -Constant* LLVMContext::getConstantExprAlignOf(const Type* Ty) { - return ConstantExpr::getAlignOf(Ty); -} - -Constant* LLVMContext::getConstantExprCompare(unsigned short pred, - Constant* C1, Constant* C2) { - return ConstantExpr::getCompare(pred, C1, C2); -} - -Constant* LLVMContext::getConstantExprNeg(Constant* C) { - return ConstantExpr::getNeg(C); -} - -Constant* LLVMContext::getConstantExprFNeg(Constant* C) { - return ConstantExpr::getFNeg(C); -} - -Constant* LLVMContext::getConstantExprNot(Constant* C) { - return ConstantExpr::getNot(C); -} - -Constant* LLVMContext::getConstantExprAdd(Constant* C1, Constant* C2) { - return ConstantExpr::getAdd(C1, C2); -} - -Constant* LLVMContext::getConstantExprFAdd(Constant* C1, Constant* C2) { - return ConstantExpr::getFAdd(C1, C2); -} - -Constant* LLVMContext::getConstantExprSub(Constant* C1, Constant* C2) { - return ConstantExpr::getSub(C1, C2); -} - -Constant* LLVMContext::getConstantExprFSub(Constant* C1, Constant* C2) { - return ConstantExpr::getFSub(C1, C2); -} - -Constant* LLVMContext::getConstantExprMul(Constant* C1, Constant* C2) { - return ConstantExpr::getMul(C1, C2); -} - -Constant* LLVMContext::getConstantExprFMul(Constant* C1, Constant* C2) { - return ConstantExpr::getFMul(C1, C2); -} - -Constant* LLVMContext::getConstantExprUDiv(Constant* C1, Constant* C2) { - return ConstantExpr::getUDiv(C1, C2); -} - -Constant* LLVMContext::getConstantExprSDiv(Constant* C1, Constant* C2) { - return ConstantExpr::getSDiv(C1, C2); -} - -Constant* LLVMContext::getConstantExprFDiv(Constant* C1, Constant* C2) { - return ConstantExpr::getFDiv(C1, C2); -} - -Constant* LLVMContext::getConstantExprURem(Constant* C1, Constant* C2) { - return ConstantExpr::getURem(C1, C2); -} - -Constant* LLVMContext::getConstantExprSRem(Constant* C1, Constant* C2) { - return ConstantExpr::getSRem(C1, C2); -} - -Constant* LLVMContext::getConstantExprFRem(Constant* C1, Constant* C2) { - return ConstantExpr::getFRem(C1, C2); -} - -Constant* LLVMContext::getConstantExprAnd(Constant* C1, Constant* C2) { - return ConstantExpr::getAnd(C1, C2); -} - -Constant* LLVMContext::getConstantExprOr(Constant* C1, Constant* C2) { - return ConstantExpr::getOr(C1, C2); -} - -Constant* LLVMContext::getConstantExprXor(Constant* C1, Constant* C2) { - return ConstantExpr::getXor(C1, C2); -} - -Constant* LLVMContext::getConstantExprICmp(unsigned short pred, Constant* LHS, - Constant* RHS) { - return ConstantExpr::getICmp(pred, LHS, RHS); -} - -Constant* LLVMContext::getConstantExprFCmp(unsigned short pred, Constant* LHS, - Constant* RHS) { - return ConstantExpr::getFCmp(pred, LHS, RHS); -} - -Constant* LLVMContext::getConstantExprVICmp(unsigned short pred, Constant* LHS, - Constant* RHS) { - return ConstantExpr::getVICmp(pred, LHS, RHS); -} - -Constant* LLVMContext::getConstantExprVFCmp(unsigned short pred, Constant* LHS, - Constant* RHS) { - return ConstantExpr::getVFCmp(pred, LHS, RHS); -} - -Constant* LLVMContext::getConstantExprShl(Constant* C1, Constant* C2) { - return ConstantExpr::getShl(C1, C2); -} - -Constant* LLVMContext::getConstantExprLShr(Constant* C1, Constant* C2) { - return ConstantExpr::getLShr(C1, C2); -} - -Constant* LLVMContext::getConstantExprAShr(Constant* C1, Constant* C2) { - return ConstantExpr::getAShr(C1, C2); -} - -Constant* LLVMContext::getConstantExprGetElementPtr(Constant* C, - Constant* const* IdxList, - unsigned NumIdx) { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); -} - -Constant* LLVMContext::getConstantExprGetElementPtr(Constant* C, - Value* const* IdxList, - unsigned NumIdx) { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); -} - -Constant* LLVMContext::getConstantExprExtractElement(Constant* Vec, - Constant* Idx) { - return ConstantExpr::getExtractElement(Vec, Idx); -} - -Constant* LLVMContext::getConstantExprInsertElement(Constant* Vec, - Constant* Elt, - Constant* Idx) { - return ConstantExpr::getInsertElement(Vec, Elt, Idx); -} - -Constant* LLVMContext::getConstantExprShuffleVector(Constant* V1, Constant* V2, - Constant* Mask) { - return ConstantExpr::getShuffleVector(V1, V2, Mask); -} - -Constant* LLVMContext::getConstantExprExtractValue(Constant* Agg, - const unsigned* IdxList, - unsigned NumIdx) { - return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx); -} - -Constant* LLVMContext::getConstantExprInsertValue(Constant* Agg, Constant* Val, - const unsigned* IdxList, - unsigned NumIdx) { - return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx); -} - -Constant* LLVMContext::getZeroValueForNegation(const Type* Ty) { - return ConstantExpr::getZeroValueForNegationExpr(Ty); -} - - -// ConstantFP accessors. -ConstantFP* LLVMContext::getConstantFP(const APFloat& V) { - return ConstantFP::get(V); -} - -Constant* LLVMContext::getConstantFP(const Type* Ty, double V) { - return ConstantFP::get(Ty, V); -} - -ConstantFP* LLVMContext::getConstantFPNegativeZero(const Type* Ty) { - return ConstantFP::getNegativeZero(Ty); -} - - -// ConstantVector accessors. -Constant* LLVMContext::getConstantVector(const VectorType* T, - const std::vector<Constant*>& V) { - return ConstantVector::get(T, V); -} - -Constant* LLVMContext::getConstantVector(const std::vector<Constant*>& V) { - return ConstantVector::get(V); -} - -Constant* LLVMContext::getConstantVector(Constant* const* Vals, - unsigned NumVals) { - return ConstantVector::get(Vals, NumVals); -} - -ConstantVector* LLVMContext::getConstantVectorAllOnesValue( - const VectorType* Ty) { - return ConstantVector::getAllOnesValue(Ty); -} - -// MDNode accessors -MDNode* LLVMContext::getMDNode(Value* const* Vals, unsigned NumVals) { - return MDNode::get(Vals, NumVals); -} - -// MDString accessors -MDString* LLVMContext::getMDString(const char *StrBegin, const char *StrEnd) { - return MDString::get(StrBegin, StrEnd); -} - -MDString* LLVMContext::getMDString(const std::string &Str) { - return MDString::get(Str); -} - -// FunctionType accessors -FunctionType* LLVMContext::getFunctionType(const Type* Result, - const std::vector<const Type*>& Params, - bool isVarArg) { - return FunctionType::get(Result, Params, isVarArg); -} - -// IntegerType accessors -const IntegerType* LLVMContext::getIntegerType(unsigned NumBits) { - return IntegerType::get(NumBits); -} - -// OpaqueType accessors -OpaqueType* LLVMContext::getOpaqueType() { - return OpaqueType::get(); -} - -// StructType accessors -StructType* LLVMContext::getStructType(bool isPacked) { - return StructType::get(isPacked); -} - -StructType* LLVMContext::getStructType(const std::vector<const Type*>& Params, - bool isPacked) { - return StructType::get(Params, isPacked); -} - -// ArrayType accessors -ArrayType* LLVMContext::getArrayType(const Type* ElementType, - uint64_t NumElements) { - return ArrayType::get(ElementType, NumElements); -} - -// PointerType accessors -PointerType* LLVMContext::getPointerType(const Type* ElementType, - unsigned AddressSpace) { - return PointerType::get(ElementType, AddressSpace); -} - -PointerType* LLVMContext::getPointerTypeUnqual(const Type* ElementType) { - return PointerType::getUnqual(ElementType); -} - -// VectorType accessors -VectorType* LLVMContext::getVectorType(const Type* ElementType, - unsigned NumElements) { - return VectorType::get(ElementType, NumElements); -} - -VectorType* LLVMContext::getVectorTypeInteger(const VectorType* VTy) { - return VectorType::getInteger(VTy); -} - -VectorType* LLVMContext::getVectorTypeExtendedElement(const VectorType* VTy) { - return VectorType::getExtendedElementVectorType(VTy); -} - -VectorType* LLVMContext::getVectorTypeTruncatedElement(const VectorType* VTy) { - return VectorType::getTruncatedElementVectorType(VTy); +GetElementPtrConstantExpr::GetElementPtrConstantExpr + (Constant *C, + const std::vector<Constant*> &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + OperandTraits<GetElementPtrConstantExpr>::op_end(this) + - (IdxList.size()+1), + IdxList.size()+1) { + OperandList[0] = C; + for (unsigned i = 0, E = IdxList.size(); i != E; ++i) + OperandList[i+1] = IdxList[i]; +} + +bool LLVMContext::RemoveDeadMetadata() { + std::vector<WeakVH> DeadMDNodes; + bool Changed = false; + while (1) { + + for (FoldingSet<MDNode>::iterator + I = pImpl->MDNodeSet.begin(), + E = pImpl->MDNodeSet.end(); I != E; ++I) { + MDNode *N = &(*I); + if (N->use_empty()) + DeadMDNodes.push_back(WeakVH(N)); + } + + if (DeadMDNodes.empty()) + return Changed; + + while (!DeadMDNodes.empty()) { + Value *V = DeadMDNodes.back(); DeadMDNodes.pop_back(); + if (const MDNode *N = dyn_cast_or_null<MDNode>(V)) + if (N->use_empty()) + delete N; + } + } + return Changed; +} + +MetadataContext &LLVMContext::getMetadata() { + return pImpl->TheMetadata; } diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 4e089fb661cf..83888c3907bf 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -1,4 +1,4 @@ -//===-- llvm/SymbolTableListTraitsImpl.h - Implementation ------*- C++ -*--===// +//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class --------------===// // // The LLVM Compiler Infrastructure // @@ -15,9 +15,209 @@ #ifndef LLVM_LLVMCONTEXT_IMPL_H #define LLVM_LLVMCONTEXT_IMPL_H +#include "ConstantsContext.h" +#include "LeaksContext.h" +#include "TypesContext.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/System/Mutex.h" +#include "llvm/System/RWMutex.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringMap.h" +#include <vector> + namespace llvm { + +class ConstantInt; +class ConstantFP; +class MDString; +class MDNode; +class LLVMContext; +class Type; +class Value; + +struct DenseMapAPIntKeyInfo { + struct KeyTy { + APInt val; + const Type* type; + KeyTy(const APInt& V, const Type* Ty) : val(V), type(Ty) {} + KeyTy(const KeyTy& that) : val(that.val), type(that.type) {} + bool operator==(const KeyTy& that) const { + return type == that.type && this->val == that.val; + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + }; + static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); } + static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); } + static unsigned getHashValue(const KeyTy &Key) { + return DenseMapInfo<void*>::getHashValue(Key.type) ^ + Key.val.getHashValue(); + } + static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { + return LHS == RHS; + } + static bool isPod() { return false; } +}; + +struct DenseMapAPFloatKeyInfo { + struct KeyTy { + APFloat val; + KeyTy(const APFloat& V) : val(V){} + KeyTy(const KeyTy& that) : val(that.val) {} + bool operator==(const KeyTy& that) const { + return this->val.bitwiseIsEqual(that.val); + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + }; + static inline KeyTy getEmptyKey() { + return KeyTy(APFloat(APFloat::Bogus,1)); + } + static inline KeyTy getTombstoneKey() { + return KeyTy(APFloat(APFloat::Bogus,2)); + } + static unsigned getHashValue(const KeyTy &Key) { + return Key.val.getHashValue(); + } + static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { + return LHS == RHS; + } + static bool isPod() { return false; } +}; + class LLVMContextImpl { +public: + sys::SmartRWMutex<true> ConstantsLock; + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, + DenseMapAPIntKeyInfo> IntMapTy; + IntMapTy IntConstants; + + typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, + DenseMapAPFloatKeyInfo> FPMapTy; + FPMapTy FPConstants; + + StringMap<MDString*> MDStringCache; + + FoldingSet<MDNode> MDNodeSet; + + ValueMap<char, Type, ConstantAggregateZero> AggZeroConstants; + + typedef ValueMap<std::vector<Constant*>, ArrayType, + ConstantArray, true /*largekey*/> ArrayConstantsTy; + ArrayConstantsTy ArrayConstants; + + typedef ValueMap<std::vector<Constant*>, StructType, + ConstantStruct, true /*largekey*/> StructConstantsTy; + StructConstantsTy StructConstants; + + typedef ValueMap<std::vector<Constant*>, VectorType, + ConstantVector> VectorConstantsTy; + VectorConstantsTy VectorConstants; + + ValueMap<char, PointerType, ConstantPointerNull> NullPtrConstants; + + ValueMap<char, Type, UndefValue> UndefValueConstants; + + ValueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants; + + ConstantInt *TheTrueVal; + ConstantInt *TheFalseVal; + + // Lock used for guarding access to the leak detector + sys::SmartMutex<true> LLVMObjectsLock; + LeakDetectorImpl<Value> LLVMObjects; + + // Lock used for guarding access to the type maps. + sys::SmartMutex<true> TypeMapLock; + + // Recursive lock used for guarding access to AbstractTypeUsers. + // NOTE: The true template parameter means this will no-op when we're not in + // multithreaded mode. + sys::SmartMutex<true> AbstractTypeUsersLock; + + // Basic type instances. + const Type VoidTy; + const Type LabelTy; + const Type FloatTy; + const Type DoubleTy; + const Type MetadataTy; + const Type X86_FP80Ty; + const Type FP128Ty; + const Type PPC_FP128Ty; + const IntegerType Int1Ty; + const IntegerType Int8Ty; + const IntegerType Int16Ty; + const IntegerType Int32Ty; + const IntegerType Int64Ty; + + // Concrete/Abstract TypeDescriptions - We lazily calculate type descriptions + // for types as they are needed. Because resolution of types must invalidate + // all of the abstract type descriptions, we keep them in a seperate map to + // make this easy. + TypePrinting ConcreteTypeDescriptions; + TypePrinting AbstractTypeDescriptions; + + TypeMap<ArrayValType, ArrayType> ArrayTypes; + TypeMap<VectorValType, VectorType> VectorTypes; + TypeMap<PointerValType, PointerType> PointerTypes; + TypeMap<FunctionValType, FunctionType> FunctionTypes; + TypeMap<StructValType, StructType> StructTypes; + TypeMap<IntegerValType, IntegerType> IntegerTypes; + + /// ValueHandles - This map keeps track of all of the value handles that are + /// watching a Value*. The Value::HasValueHandle bit is used to know + // whether or not a value has an entry in this map. + typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy; + ValueHandlesTy ValueHandles; + + MetadataContext TheMetadata; + LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0), + VoidTy(C, Type::VoidTyID), + LabelTy(C, Type::LabelTyID), + FloatTy(C, Type::FloatTyID), + DoubleTy(C, Type::DoubleTyID), + MetadataTy(C, Type::MetadataTyID), + X86_FP80Ty(C, Type::X86_FP80TyID), + FP128Ty(C, Type::FP128TyID), + PPC_FP128Ty(C, Type::PPC_FP128TyID), + Int1Ty(C, 1), + Int8Ty(C, 8), + Int16Ty(C, 16), + Int32Ty(C, 32), + Int64Ty(C, 64) { } + ~LLVMContextImpl() + { + ExprConstants.freeConstants(); + ArrayConstants.freeConstants(); + StructConstants.freeConstants(); + VectorConstants.freeConstants(); + AggZeroConstants.freeConstants(); + NullPtrConstants.freeConstants(); + UndefValueConstants.freeConstants(); + for (FoldingSet<MDNode>::iterator I = MDNodeSet.begin(), + E = MDNodeSet.end(); I != E; ++I) + I->dropAllReferences(); + for (IntMapTy::iterator I = IntConstants.begin(), E = IntConstants.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + for (FPMapTy::iterator I = FPConstants.begin(), E = FPConstants.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + } }; } diff --git a/lib/VMCore/LeakDetector.cpp b/lib/VMCore/LeakDetector.cpp index b5926bcf441a..5ebd4f5ac03b 100644 --- a/lib/VMCore/LeakDetector.cpp +++ b/lib/VMCore/LeakDetector.cpp @@ -11,129 +11,62 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/Support/LeakDetector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Streams.h" -#include "llvm/System/RWMutex.h" +#include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" #include "llvm/Value.h" using namespace llvm; -namespace { - template <class T> - struct VISIBILITY_HIDDEN PrinterTrait { - static void print(const T* P) { cerr << P; } - }; +static ManagedStatic<sys::SmartMutex<true> > ObjectsLock; +static ManagedStatic<LeakDetectorImpl<void> > Objects; - template<> - struct VISIBILITY_HIDDEN PrinterTrait<Value> { - static void print(const Value* P) { cerr << *P; } - }; - - ManagedStatic<sys::SmartRWMutex<true> > LeakDetectorLock; - - template <typename T> - struct VISIBILITY_HIDDEN LeakDetectorImpl { - explicit LeakDetectorImpl(const char* const name = "") : - Cache(0), Name(name) { } - - void clear() { - Cache = 0; - Ts.clear(); - } - - void setName(const char* n) { - Name = n; - } - - // Because the most common usage pattern, by far, is to add a - // garbage object, then remove it immediately, we optimize this - // case. When an object is added, it is not added to the set - // immediately, it is added to the CachedValue Value. If it is - // immediately removed, no set search need be performed. - void addGarbage(const T* o) { - sys::SmartScopedWriter<true> Writer(&*LeakDetectorLock); - if (Cache) { - assert(Ts.count(Cache) == 0 && "Object already in set!"); - Ts.insert(Cache); - } - Cache = o; - } - - void removeGarbage(const T* o) { - sys::SmartScopedWriter<true> Writer(&*LeakDetectorLock); - if (o == Cache) - Cache = 0; // Cache hit - else - Ts.erase(o); - } - - bool hasGarbage(const std::string& Message) { - addGarbage(0); // Flush the Cache - - sys::SmartScopedReader<true> Reader(&*LeakDetectorLock); - assert(Cache == 0 && "No value should be cached anymore!"); - - if (!Ts.empty()) { - cerr << "Leaked " << Name << " objects found: " << Message << ":\n"; - for (typename SmallPtrSet<const T*, 8>::iterator I = Ts.begin(), - E = Ts.end(); I != E; ++I) { - cerr << "\t"; - PrinterTrait<T>::print(*I); - cerr << "\n"; - } - cerr << '\n'; - - return true; - } - - return false; - } - - private: - SmallPtrSet<const T*, 8> Ts; - const T* Cache; - const char* Name; - }; - - static ManagedStatic<LeakDetectorImpl<void> > Objects; - static ManagedStatic<LeakDetectorImpl<Value> > LLVMObjects; - - static void clearGarbage() { - Objects->clear(); - LLVMObjects->clear(); - } +static void clearGarbage(LLVMContext &Context) { + Objects->clear(); + Context.pImpl->LLVMObjects.clear(); } void LeakDetector::addGarbageObjectImpl(void *Object) { + sys::SmartScopedLock<true> Lock(*ObjectsLock); Objects->addGarbage(Object); } void LeakDetector::addGarbageObjectImpl(const Value *Object) { - LLVMObjects->addGarbage(Object); + LLVMContextImpl *pImpl = Object->getContext().pImpl; + sys::SmartScopedLock<true> Lock(pImpl->LLVMObjectsLock); + pImpl->LLVMObjects.addGarbage(Object); } void LeakDetector::removeGarbageObjectImpl(void *Object) { + sys::SmartScopedLock<true> Lock(*ObjectsLock); Objects->removeGarbage(Object); } void LeakDetector::removeGarbageObjectImpl(const Value *Object) { - LLVMObjects->removeGarbage(Object); + LLVMContextImpl *pImpl = Object->getContext().pImpl; + sys::SmartScopedLock<true> Lock(pImpl->LLVMObjectsLock); + pImpl->LLVMObjects.removeGarbage(Object); } -void LeakDetector::checkForGarbageImpl(const std::string &Message) { +void LeakDetector::checkForGarbageImpl(LLVMContext &Context, + const std::string &Message) { + LLVMContextImpl *pImpl = Context.pImpl; + sys::SmartScopedLock<true> Lock(*ObjectsLock); + sys::SmartScopedLock<true> CLock(pImpl->LLVMObjectsLock); + Objects->setName("GENERIC"); - LLVMObjects->setName("LLVM"); + pImpl->LLVMObjects.setName("LLVM"); // use non-short-circuit version so that both checks are performed if (Objects->hasGarbage(Message) | - LLVMObjects->hasGarbage(Message)) - cerr << "\nThis is probably because you removed an object, but didn't " - << "delete it. Please check your code for memory leaks.\n"; + pImpl->LLVMObjects.hasGarbage(Message)) + errs() << "\nThis is probably because you removed an object, but didn't " + << "delete it. Please check your code for memory leaks.\n"; // Clear out results so we don't get duplicate warnings on // next call... - clearGarbage(); + clearGarbage(Context); } diff --git a/lib/VMCore/LeaksContext.h b/lib/VMCore/LeaksContext.h new file mode 100644 index 000000000000..b0c3a14fe84a --- /dev/null +++ b/lib/VMCore/LeaksContext.h @@ -0,0 +1,89 @@ +//===- LeaksContext.h - LeadDetector Implementation ------------*- 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 various helper methods and classes used by +// LLVMContextImpl for leaks detectors. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Value.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +template <class T> +struct PrinterTrait { + static void print(const T* P) { errs() << P; } +}; + +template<> +struct PrinterTrait<Value> { + static void print(const Value* P) { errs() << *P; } +}; + +template <typename T> +struct LeakDetectorImpl { + explicit LeakDetectorImpl(const char* const name = "") : + Cache(0), Name(name) { } + + void clear() { + Cache = 0; + Ts.clear(); + } + + void setName(const char* n) { + Name = n; + } + + // Because the most common usage pattern, by far, is to add a + // garbage object, then remove it immediately, we optimize this + // case. When an object is added, it is not added to the set + // immediately, it is added to the CachedValue Value. If it is + // immediately removed, no set search need be performed. + void addGarbage(const T* o) { + if (Cache) { + assert(Ts.count(Cache) == 0 && "Object already in set!"); + Ts.insert(Cache); + } + Cache = o; + } + + void removeGarbage(const T* o) { + if (o == Cache) + Cache = 0; // Cache hit + else + Ts.erase(o); + } + + bool hasGarbage(const std::string& Message) { + addGarbage(0); // Flush the Cache + + assert(Cache == 0 && "No value should be cached anymore!"); + + if (!Ts.empty()) { + errs() << "Leaked " << Name << " objects found: " << Message << ":\n"; + for (typename SmallPtrSet<const T*, 8>::iterator I = Ts.begin(), + E = Ts.end(); I != E; ++I) { + errs() << '\t'; + PrinterTrait<T>::print(*I); + errs() << '\n'; + } + errs() << '\n'; + + return true; + } + + return false; + } + +private: + SmallPtrSet<const T*, 8> Ts; + const T* Cache; + const char* Name; +}; diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index 1a68b890542f..33eb0449e824 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -12,12 +12,12 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Mangler.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/System/Atomic.h" +#include "llvm/Function.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; static char HexDigit(int V) { @@ -32,13 +32,9 @@ static std::string MangleLetter(unsigned char C) { /// makeNameProper - We don't want identifier names non-C-identifier characters /// in them, so mangle them as appropriate. /// -std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, - const char *PrivatePrefix) { - if (X.empty()) return X; // Empty names are uniqued by the caller. - - // If PreserveAsmNames is set, names with asm identifiers are not modified. - if (PreserveAsmNames && X[0] == 1) - return X; +std::string Mangler::makeNameProper(const std::string &X, + ManglerPrefixTy PrefixTy) { + assert(!X.empty() && "Cannot mangle empty strings"); if (!UseQuotes) { std::string Result; @@ -51,8 +47,9 @@ std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, ++I; // Skip over the marker. } - // Mangle the first letter specially, don't allow numbers. - if (*I >= '0' && *I <= '9') + // Mangle the first letter specially, don't allow numbers unless the target + // explicitly allows them. + if (!SymbolsCanStartWithDigit && *I >= '0' && *I <= '9') Result += MangleLetter(*I++); for (std::string::const_iterator E = X.end(); I != E; ++I) { @@ -63,11 +60,14 @@ std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, } if (NeedPrefix) { - if (Prefix) - Result = Prefix + Result; - if (PrivatePrefix) + Result = Prefix + Result; + + if (PrefixTy == Mangler::Private) Result = PrivatePrefix + Result; + else if (PrefixTy == Mangler::LinkerPrivate) + Result = LinkerPrivatePrefix + Result; } + return Result; } @@ -95,17 +95,21 @@ std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, // In the common case, we don't need quotes. Handle this quickly. if (!NeedQuotes) { - if (NeedPrefix) { - if (Prefix) - Result = Prefix + X; - else - Result = X; - if (PrivatePrefix) - Result = PrivatePrefix + Result; - return Result; - } else - return X.substr(1); + if (!NeedPrefix) + return X.substr(1); // Strip off the \001. + + Result = Prefix + X; + + if (PrefixTy == Mangler::Private) + Result = PrivatePrefix + Result; + else if (PrefixTy == Mangler::LinkerPrivate) + Result = LinkerPrivatePrefix + Result; + + return Result; } + + if (NeedPrefix) + Result = X.substr(0, I-X.begin()); // Otherwise, construct the string the expensive way. for (std::string::const_iterator E = X.end(); I != E; ++I) { @@ -118,72 +122,93 @@ std::string Mangler::makeNameProper(const std::string &X, const char *Prefix, } if (NeedPrefix) { - if (Prefix) - Result = Prefix + X; - else - Result = X; - if (PrivatePrefix) + Result = Prefix + Result; + + if (PrefixTy == Mangler::Private) Result = PrivatePrefix + Result; + else if (PrefixTy == Mangler::LinkerPrivate) + Result = LinkerPrivatePrefix + Result; } + Result = '"' + Result + '"'; return Result; } -/// getTypeID - Return a unique ID for the specified LLVM type. +/// getMangledName - Returns the mangled name of V, an LLVM Value, +/// in the current module. If 'Suffix' is specified, the name ends with the +/// specified suffix. If 'ForcePrivate' is specified, the label is specified +/// to have a private label prefix. /// -unsigned Mangler::getTypeID(const Type *Ty) { - unsigned &E = TypeMap[Ty]; - if (E == 0) E = ++TypeCounter; - return E; -} +std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix, + bool ForcePrivate) { + assert((!isa<Function>(GV) || !cast<Function>(GV)->isIntrinsic()) && + "Intrinsic functions cannot be mangled by Mangler"); -std::string Mangler::getValueName(const Value *V) { - if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) - return getValueName(GV); + ManglerPrefixTy PrefixTy = + (GV->hasPrivateLinkage() || ForcePrivate) ? Mangler::Private : + GV->hasLinkerPrivateLinkage() ? Mangler::LinkerPrivate : Mangler::Default; + + if (GV->hasName()) + return makeNameProper(GV->getNameStr() + Suffix, PrefixTy); - std::string &Name = Memo[V]; - if (!Name.empty()) - return Name; // Return the already-computed name for V. + // Get the ID for the global, assigning a new one if we haven't got one + // already. + unsigned &ID = AnonGlobalIDs[GV]; + if (ID == 0) ID = NextAnonGlobalID++; - // Always mangle local names. - Name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType())); - return Name; + // Must mangle the global into a unique ID. + return makeNameProper("__unnamed_" + utostr(ID) + Suffix, PrefixTy); } -std::string Mangler::getValueName(const GlobalValue *GV, const char * Suffix) { - // Check to see whether we've already named V. - std::string &Name = Memo[GV]; - if (!Name.empty()) - return Name; // Return the already-computed name for V. - - // Name mangling occurs as follows: - // - If V is an intrinsic function, do not change name at all - // - Otherwise, mangling occurs if global collides with existing name. - if (isa<Function>(GV) && cast<Function>(GV)->isIntrinsic()) { - Name = GV->getNameStart(); // Is an intrinsic function - } else if (!GV->hasName()) { - // Must mangle the global into a unique ID. - unsigned TypeUniqueID = getTypeID(GV->getType()); - static uint32_t GlobalID = 0; - - unsigned OldID = GlobalID; - sys::AtomicIncrement(&GlobalID); +/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix +/// and the specified global variable's name. If the global variable doesn't +/// have a name, this fills in a unique name for the global. +void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, + const GlobalValue *GV, + bool isImplicitlyPrivate) { + + // If the global is anonymous or not led with \1, then add the appropriate + // prefix. + if (!GV->hasName() || GV->getName()[0] != '\1') { + if (GV->hasPrivateLinkage() || isImplicitlyPrivate) + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + else if (GV->hasLinkerPrivateLinkage()) + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));; + OutName.append(Prefix, Prefix+strlen(Prefix)); + } + + // If the global has a name, just append it now. + if (GV->hasName()) { + StringRef Name = GV->getName(); - Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(OldID); - } else { - if (GV->hasPrivateLinkage()) - Name = makeNameProper(GV->getName() + Suffix, Prefix, PrivatePrefix); + // Strip off the prefix marker if present. + if (Name[0] != '\1') + OutName.append(Name.begin(), Name.end()); else - Name = makeNameProper(GV->getName() + Suffix, Prefix); + OutName.append(Name.begin()+1, Name.end()); + return; } - - return Name; + + // If the global variable doesn't have a name, return a unique name for the + // global based on a numbering. + + // Get the ID for the global, assigning a new one if we haven't got one + // already. + unsigned &ID = AnonGlobalIDs[GV]; + if (ID == 0) ID = NextAnonGlobalID++; + + // Must mangle the global into a unique ID. + raw_svector_ostream(OutName) << "__unnamed_" << ID; } -Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix) - : Prefix(prefix), PrivatePrefix (privatePrefix), UseQuotes(false), - PreserveAsmNames(false), Count(0), TypeCounter(0) { + +Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix, + const char *linkerPrivatePrefix) + : Prefix(prefix), PrivatePrefix(privatePrefix), + LinkerPrivatePrefix(linkerPrivatePrefix), UseQuotes(false), + SymbolsCanStartWithDigit(false), NextAnonGlobalID(1) { std::fill(AcceptableChars, array_endof(AcceptableChars), 0); // Letters and numbers are acceptable. @@ -198,4 +223,5 @@ Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix) markCharAcceptable('_'); markCharAcceptable('$'); markCharAcceptable('.'); + markCharAcceptable('@'); } diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp new file mode 100644 index 000000000000..110c5e38fac3 --- /dev/null +++ b/lib/VMCore/Metadata.cpp @@ -0,0 +1,433 @@ +//===-- Metadata.cpp - Implement Metadata classes -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the Metadata classes. +// +//===----------------------------------------------------------------------===// + +#include "LLVMContextImpl.h" +#include "llvm/Metadata.h" +#include "llvm/LLVMContext.h" +#include "llvm/Module.h" +#include "llvm/Instruction.h" +#include "SymbolTableListTraitsImpl.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +//MetadataBase implementation +// + +/// resizeOperands - Metadata keeps track of other metadata uses using +/// OperandList. Resize this list to hold anticipated number of metadata +/// operands. +void MetadataBase::resizeOperands(unsigned NumOps) { + unsigned e = getNumOperands(); + if (NumOps == 0) { + NumOps = e*2; + if (NumOps < 2) NumOps = 2; + } else if (NumOps > NumOperands) { + // No resize needed. + if (ReservedSpace >= NumOps) return; + } else if (NumOps == NumOperands) { + if (ReservedSpace == NumOps) return; + } else { + return; + } + + ReservedSpace = NumOps; + Use *OldOps = OperandList; + Use *NewOps = allocHungoffUses(NumOps); + std::copy(OldOps, OldOps + e, NewOps); + OperandList = NewOps; + if (OldOps) Use::zap(OldOps, OldOps + e, true); +} +//===----------------------------------------------------------------------===// +//MDString implementation +// +MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { + LLVMContextImpl *pImpl = Context.pImpl; + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + StringMapEntry<MDString *> &Entry = + pImpl->MDStringCache.GetOrCreateValue(Str); + MDString *&S = Entry.getValue(); + if (!S) S = new MDString(Context, Entry.getKeyData(), + Entry.getKeyLength()); + + return S; +} + +//===----------------------------------------------------------------------===// +//MDNode implementation +// +MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals) + : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) { + NumOperands = 0; + resizeOperands(NumVals); + for (unsigned i = 0; i != NumVals; ++i) { + // Only record metadata uses. + if (MetadataBase *MB = dyn_cast_or_null<MetadataBase>(Vals[i])) + OperandList[NumOperands++] = MB; + else if(Vals[i] && + Vals[i]->getType()->getTypeID() == Type::MetadataTyID) + OperandList[NumOperands++] = Vals[i]; + Node.push_back(ElementVH(Vals[i], this)); + } +} + +void MDNode::Profile(FoldingSetNodeID &ID) const { + for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I) + ID.AddPointer(*I); +} + +MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { + LLVMContextImpl *pImpl = Context.pImpl; + FoldingSetNodeID ID; + for (unsigned i = 0; i != NumVals; ++i) + ID.AddPointer(Vals[i]); + + pImpl->ConstantsLock.reader_acquire(); + void *InsertPoint; + MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + pImpl->ConstantsLock.reader_release(); + + if (!N) { + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + if (!N) { + // InsertPoint will have been set by the FindNodeOrInsertPos call. + N = new MDNode(Context, Vals, NumVals); + pImpl->MDNodeSet.InsertNode(N, InsertPoint); + } + } + + return N; +} + +/// dropAllReferences - Remove all uses and clear node vector. +void MDNode::dropAllReferences() { + User::dropAllReferences(); + Node.clear(); +} + +MDNode::~MDNode() { + { + LLVMContextImpl *pImpl = getType()->getContext().pImpl; + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + pImpl->MDNodeSet.RemoveNode(this); + } + dropAllReferences(); +} + +// Replace value from this node's element list. +void MDNode::replaceElement(Value *From, Value *To) { + if (From == To || !getType()) + return; + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + // Find value. This is a linear search, do something if it consumes + // lot of time. It is possible that to have multiple instances of + // From in this MDNode's element list. + SmallVector<unsigned, 4> Indexes; + unsigned Index = 0; + for (SmallVector<ElementVH, 4>::iterator I = Node.begin(), + E = Node.end(); I != E; ++I, ++Index) { + Value *V = *I; + if (V && V == From) + Indexes.push_back(Index); + } + + if (Indexes.empty()) + return; + + // Remove "this" from the context map. + { + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + pImpl->MDNodeSet.RemoveNode(this); + } + + // MDNode only lists metadata elements in operand list, because MDNode + // used by MDNode is considered a valid use. However on the side, MDNode + // using a non-metadata value is not considered a "use" of non-metadata + // value. + SmallVector<unsigned, 4> OpIndexes; + unsigned OpIndex = 0; + for (User::op_iterator OI = op_begin(), OE = op_end(); + OI != OE; ++OI, OpIndex++) { + if (*OI == From) + OpIndexes.push_back(OpIndex); + } + if (MetadataBase *MDTo = dyn_cast_or_null<MetadataBase>(To)) { + for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, MDTo); + } else { + for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, 0); + } + + // Replace From element(s) in place. + for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end(); + I != E; ++I) { + unsigned Index = *I; + Node[Index] = ElementVH(To, this); + } + + // Insert updated "this" into the context's folding node set. + // If a node with same element list already exist then before inserting + // updated "this" into the folding node set, replace all uses of existing + // node with updated "this" node. + FoldingSetNodeID ID; + Profile(ID); + pImpl->ConstantsLock.reader_acquire(); + void *InsertPoint; + MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + pImpl->ConstantsLock.reader_release(); + + if (N) { + N->replaceAllUsesWith(this); + delete N; + N = 0; + } + + { + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + if (!N) { + // InsertPoint will have been set by the FindNodeOrInsertPos call. + N = this; + pImpl->MDNodeSet.InsertNode(N, InsertPoint); + } + } +} + +//===----------------------------------------------------------------------===// +//NamedMDNode implementation +// +NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N, + MetadataBase*const* MDs, + unsigned NumMDs, Module *ParentModule) + : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) { + setName(N); + NumOperands = 0; + resizeOperands(NumMDs); + + for (unsigned i = 0; i != NumMDs; ++i) { + if (MDs[i]) + OperandList[NumOperands++] = MDs[i]; + Node.push_back(WeakMetadataVH(MDs[i])); + } + if (ParentModule) + ParentModule->getNamedMDList().push_back(this); +} + +NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) { + assert (NMD && "Invalid source NamedMDNode!"); + SmallVector<MetadataBase *, 4> Elems; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) + Elems.push_back(NMD->getElement(i)); + return new NamedMDNode(NMD->getContext(), NMD->getName().data(), + Elems.data(), Elems.size(), M); +} + +/// eraseFromParent - Drop all references and remove the node from parent +/// module. +void NamedMDNode::eraseFromParent() { + getParent()->getNamedMDList().erase(this); +} + +/// dropAllReferences - Remove all uses and clear node vector. +void NamedMDNode::dropAllReferences() { + User::dropAllReferences(); + Node.clear(); +} + +NamedMDNode::~NamedMDNode() { + dropAllReferences(); +} + +//===----------------------------------------------------------------------===// +//Metadata implementation +// + +/// RegisterMDKind - Register a new metadata kind and return its ID. +/// A metadata kind can be registered only once. +unsigned MetadataContext::RegisterMDKind(const char *Name) { + assert (validName(Name) && "Invalid custome metadata name!"); + unsigned Count = MDHandlerNames.size(); + assert(MDHandlerNames.find(Name) == MDHandlerNames.end() + && "Already registered MDKind!"); + MDHandlerNames[Name] = Count + 1; + return Count + 1; +} + +/// validName - Return true if Name is a valid custom metadata handler name. +bool MetadataContext::validName(const char *Name) { + if (!Name) + return false; + + if (!isalpha(*Name)) + return false; + + unsigned Length = strlen(Name); + unsigned Count = 1; + ++Name; + while (Name && + (isalnum(*Name) || *Name == '_' || *Name == '-' || *Name == '.')) { + ++Name; + ++Count; + } + if (Length != Count) + return false; + return true; +} + +/// getMDKind - Return metadata kind. If the requested metadata kind +/// is not registered then return 0. +unsigned MetadataContext::getMDKind(const char *Name) { + assert (validName(Name) && "Invalid custome metadata name!"); + StringMap<unsigned>::iterator I = MDHandlerNames.find(Name); + if (I == MDHandlerNames.end()) + return 0; + + return I->getValue(); +} + +/// addMD - Attach the metadata of given kind with an Instruction. +void MetadataContext::addMD(unsigned MDKind, MDNode *Node, Instruction *Inst) { + assert (Node && "Unable to add custome metadata"); + Inst->HasMetadata = true; + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) { + MDMapTy Info; + Info.push_back(std::make_pair(MDKind, Node)); + MetadataStore.insert(std::make_pair(Inst, Info)); + return; + } + + MDMapTy &Info = I->second; + // If there is an entry for this MDKind then replace it. + for (unsigned i = 0, e = Info.size(); i != e; ++i) { + MDPairTy &P = Info[i]; + if (P.first == MDKind) { + Info[i] = std::make_pair(MDKind, Node); + return; + } + } + + // Otherwise add a new entry. + Info.push_back(std::make_pair(MDKind, Node)); + return; +} + +/// removeMD - Remove metadata of given kind attached with an instuction. +void MetadataContext::removeMD(unsigned Kind, Instruction *Inst) { + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return; + + MDMapTy &Info = I->second; + for (MDMapTy::iterator MI = Info.begin(), ME = Info.end(); MI != ME; ++MI) { + MDPairTy &P = *MI; + if (P.first == Kind) { + Info.erase(MI); + return; + } + } + + return; +} + +/// removeMDs - Remove all metadata attached with an instruction. +void MetadataContext::removeMDs(const Instruction *Inst) { + // Find Metadata handles for this instruction. + MDStoreTy::iterator I = MetadataStore.find(Inst); + assert (I != MetadataStore.end() && "Invalid custom metadata info!"); + MDMapTy &Info = I->second; + + // FIXME : Give all metadata handlers a chance to adjust. + + // Remove the entries for this instruction. + Info.clear(); + MetadataStore.erase(I); +} + +/// copyMD - If metadata is attached with Instruction In1 then attach +/// the same metadata to In2. +void MetadataContext::copyMD(Instruction *In1, Instruction *In2) { + assert (In1 && In2 && "Invalid instruction!"); + MDStoreTy::iterator I = MetadataStore.find(In1); + if (I == MetadataStore.end()) + return; + + MDMapTy &In1Info = I->second; + MDMapTy In2Info; + for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) + if (MDNode *MD = dyn_cast_or_null<MDNode>(I->second)) + addMD(I->first, MD, In2); +} + +/// getMD - Get the metadata of given kind attached with an Instruction. +/// If the metadata is not found then return 0. +MDNode *MetadataContext::getMD(unsigned MDKind, const Instruction *Inst) { + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return NULL; + + MDMapTy &Info = I->second; + for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; ++I) + if (I->first == MDKind) + return dyn_cast_or_null<MDNode>(I->second); + return NULL; +} + +/// getMDs - Get the metadata attached with an Instruction. +const MetadataContext::MDMapTy *MetadataContext::getMDs(const Instruction *Inst) { + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return NULL; + + return &(I->second); +} + +/// getHandlerNames - Get handler names. This is used by bitcode +/// writer. +const StringMap<unsigned> *MetadataContext::getHandlerNames() { + return &MDHandlerNames; +} + +/// ValueIsCloned - This handler is used to update metadata store +/// when In1 is cloned to create In2. +void MetadataContext::ValueIsCloned(const Instruction *In1, Instruction *In2) { + // Find Metadata handles for In1. + MDStoreTy::iterator I = MetadataStore.find(In1); + assert (I != MetadataStore.end() && "Invalid custom metadata info!"); + + // FIXME : Give all metadata handlers a chance to adjust. + + MDMapTy &In1Info = I->second; + MDMapTy In2Info; + for (MDMapTy::iterator I = In1Info.begin(), E = In1Info.end(); I != E; ++I) + if (MDNode *MD = dyn_cast_or_null<MDNode>(I->second)) + addMD(I->first, MD, In2); +} + +/// ValueIsRAUWd - This handler is used when V1's all uses are replaced by +/// V2. +void MetadataContext::ValueIsRAUWd(Value *V1, Value *V2) { + Instruction *I1 = dyn_cast<Instruction>(V1); + Instruction *I2 = dyn_cast<Instruction>(V2); + if (!I1 || !I2) + return; + + // FIXME : Give custom handlers a chance to override this. + ValueIsCloned(I1, I2); +} + diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index f057e81a649b..add24491079e 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -31,14 +31,15 @@ using namespace llvm; // GlobalVariable *ilist_traits<GlobalVariable>::createSentinel() { - GlobalVariable *Ret = new GlobalVariable(Type::Int32Ty, false, - GlobalValue::ExternalLinkage); + GlobalVariable *Ret = new GlobalVariable(getGlobalContext(), + Type::getInt32Ty(getGlobalContext()), + false, GlobalValue::ExternalLinkage); // This should not be garbage monitored. LeakDetector::removeGarbageObject(Ret); return Ret; } GlobalAlias *ilist_traits<GlobalAlias>::createSentinel() { - GlobalAlias *Ret = new GlobalAlias(Type::Int32Ty, + GlobalAlias *Ret = new GlobalAlias(Type::getInt32Ty(getGlobalContext()), GlobalValue::ExternalLinkage); // This should not be garbage monitored. LeakDetector::removeGarbageObject(Ret); @@ -55,7 +56,7 @@ template class SymbolTableListTraits<GlobalAlias, Module>; // Primitive Module methods. // -Module::Module(const std::string &MID, LLVMContext& C) +Module::Module(const StringRef &MID, LLVMContext& C) : Context(C), ModuleID(MID), DataLayout("") { ValSymTab = new ValueSymbolTable(); TypeSymTab = new TypeSymbolTable(); @@ -67,6 +68,7 @@ Module::~Module() { FunctionList.clear(); AliasList.clear(); LibraryList.clear(); + NamedMDList.clear(); delete ValSymTab; delete TypeSymTab; } @@ -113,15 +115,10 @@ Module::PointerSize Module::getPointerSize() const { /// getNamedValue - Return the first global value in the module with /// the specified name, of arbitrary type. This method returns null /// if a global with the specified name is not found. -GlobalValue *Module::getNamedValue(const std::string &Name) const { +GlobalValue *Module::getNamedValue(const StringRef &Name) const { return cast_or_null<GlobalValue>(getValueSymbolTable().lookup(Name)); } -GlobalValue *Module::getNamedValue(const char *Name) const { - llvm::Value *V = getValueSymbolTable().lookup(Name, Name+strlen(Name)); - return cast_or_null<GlobalValue>(V); -} - //===----------------------------------------------------------------------===// // Methods for easy access to the functions in the module. // @@ -131,7 +128,7 @@ GlobalValue *Module::getNamedValue(const char *Name) const { // it. This is nice because it allows most passes to get away with not handling // the symbol table directly for this common task. // -Constant *Module::getOrInsertFunction(const std::string &Name, +Constant *Module::getOrInsertFunction(const StringRef &Name, const FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. @@ -151,7 +148,7 @@ Constant *Module::getOrInsertFunction(const std::string &Name, F->setName(""); // Retry, now there won't be a conflict. Constant *NewF = getOrInsertFunction(Name, Ty); - F->setName(&Name[0], Name.size()); + F->setName(Name); return NewF; } @@ -164,7 +161,7 @@ Constant *Module::getOrInsertFunction(const std::string &Name, return F; } -Constant *Module::getOrInsertTargetIntrinsic(const std::string &Name, +Constant *Module::getOrInsertTargetIntrinsic(const StringRef &Name, const FunctionType *Ty, AttrListPtr AttributeList) { // See if we have a definition for the specified function already. @@ -181,7 +178,7 @@ Constant *Module::getOrInsertTargetIntrinsic(const std::string &Name, return F; } -Constant *Module::getOrInsertFunction(const std::string &Name, +Constant *Module::getOrInsertFunction(const StringRef &Name, const FunctionType *Ty) { AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0); return getOrInsertFunction(Name, Ty, AttributeList); @@ -192,7 +189,7 @@ Constant *Module::getOrInsertFunction(const std::string &Name, // This version of the method takes a null terminated list of function // arguments, which makes it easier for clients to use. // -Constant *Module::getOrInsertFunction(const std::string &Name, +Constant *Module::getOrInsertFunction(const StringRef &Name, AttrListPtr AttributeList, const Type *RetTy, ...) { va_list Args; @@ -206,11 +203,12 @@ Constant *Module::getOrInsertFunction(const std::string &Name, va_end(Args); // Build the function type and chain to the other getOrInsertFunction... - return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false), + return getOrInsertFunction(Name, + FunctionType::get(RetTy, ArgTys, false), AttributeList); } -Constant *Module::getOrInsertFunction(const std::string &Name, +Constant *Module::getOrInsertFunction(const StringRef &Name, const Type *RetTy, ...) { va_list Args; va_start(Args, RetTy); @@ -223,18 +221,15 @@ Constant *Module::getOrInsertFunction(const std::string &Name, va_end(Args); // Build the function type and chain to the other getOrInsertFunction... - return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false), + return getOrInsertFunction(Name, + FunctionType::get(RetTy, ArgTys, false), AttrListPtr::get((AttributeWithIndex *)0, 0)); } // getFunction - Look up the specified function in the module symbol table. // If it does not exist, return null. // -Function *Module::getFunction(const std::string &Name) const { - return dyn_cast_or_null<Function>(getNamedValue(Name)); -} - -Function *Module::getFunction(const char *Name) const { +Function *Module::getFunction(const StringRef &Name) const { return dyn_cast_or_null<Function>(getNamedValue(Name)); } @@ -249,7 +244,7 @@ Function *Module::getFunction(const char *Name) const { /// If AllowLocal is set to true, this function will return types that /// have an local. By default, these types are not returned. /// -GlobalVariable *Module::getGlobalVariable(const std::string &Name, +GlobalVariable *Module::getGlobalVariable(const StringRef &Name, bool AllowLocal) const { if (GlobalVariable *Result = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name))) @@ -264,15 +259,15 @@ GlobalVariable *Module::getGlobalVariable(const std::string &Name, /// with a constantexpr cast to the right type. /// 3. Finally, if the existing global is the correct delclaration, return the /// existing global. -Constant *Module::getOrInsertGlobal(const std::string &Name, const Type *Ty) { +Constant *Module::getOrInsertGlobal(const StringRef &Name, const Type *Ty) { // See if we have a definition for the specified global already. GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(getNamedValue(Name)); if (GV == 0) { // Nope, add it GlobalVariable *New = - new GlobalVariable(Ty, false, GlobalVariable::ExternalLinkage, 0, Name); - GlobalList.push_back(New); - return New; // Return the new declaration. + new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, + 0, Name); + return New; // Return the new declaration. } // If the variable exists but has the wrong type, return a bitcast to the @@ -291,10 +286,28 @@ Constant *Module::getOrInsertGlobal(const std::string &Name, const Type *Ty) { // getNamedAlias - Look up the specified global in the module symbol table. // If it does not exist, return null. // -GlobalAlias *Module::getNamedAlias(const std::string &Name) const { +GlobalAlias *Module::getNamedAlias(const StringRef &Name) const { return dyn_cast_or_null<GlobalAlias>(getNamedValue(Name)); } +/// getNamedMetadata - Return the first NamedMDNode in the module with the +/// specified name. This method returns null if a NamedMDNode with the +//// specified name is not found. +NamedMDNode *Module::getNamedMetadata(const StringRef &Name) const { + return dyn_cast_or_null<NamedMDNode>(getValueSymbolTable().lookup(Name)); +} + +/// getOrInsertNamedMetadata - Return the first named MDNode in the module +/// with the specified name. This method returns a new NamedMDNode if a +/// NamedMDNode with the specified name is not found. +NamedMDNode *Module::getOrInsertNamedMetadata(const StringRef &Name) { + NamedMDNode *NMD = + dyn_cast_or_null<NamedMDNode>(getValueSymbolTable().lookup(Name)); + if (!NMD) + NMD = NamedMDNode::Create(getContext(), Name, NULL, 0, this); + return NMD; +} + //===----------------------------------------------------------------------===// // Methods for easy access to the types in the module. // @@ -304,7 +317,7 @@ GlobalAlias *Module::getNamedAlias(const std::string &Name) const { // there is already an entry for this name, true is returned and the symbol // table is not modified. // -bool Module::addTypeName(const std::string &Name, const Type *Ty) { +bool Module::addTypeName(const StringRef &Name, const Type *Ty) { TypeSymbolTable &ST = getTypeSymbolTable(); if (ST.lookup(Name)) return true; // Already in symtab... @@ -318,7 +331,7 @@ bool Module::addTypeName(const std::string &Name, const Type *Ty) { /// getTypeByName - Return the type with the specified name in this module, or /// null if there is none by that name. -const Type *Module::getTypeByName(const std::string &Name) const { +const Type *Module::getTypeByName(const StringRef &Name) const { const TypeSymbolTable &ST = getTypeSymbolTable(); return cast_or_null<Type>(ST.lookup(Name)); } @@ -364,14 +377,14 @@ void Module::dropAllReferences() { I->dropAllReferences(); } -void Module::addLibrary(const std::string& Lib) { +void Module::addLibrary(const StringRef& Lib) { for (Module::lib_iterator I = lib_begin(), E = lib_end(); I != E; ++I) if (*I == Lib) return; LibraryList.push_back(Lib); } -void Module::removeLibrary(const std::string& Lib) { +void Module::removeLibrary(const StringRef& Lib) { LibraryListType::iterator I = LibraryList.begin(); LibraryListType::iterator E = LibraryList.end(); for (;I != E; ++I) diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index b037994d428b..a2831d34345e 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -19,6 +19,7 @@ #include "llvm/ModuleProvider.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/Atomic.h" #include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" @@ -45,7 +46,7 @@ bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const { // dumpPassStructure - Implement the -debug-passes=Structure option void Pass::dumpPassStructure(unsigned Offset) { - cerr << std::string(Offset*2, ' ') << getPassName() << "\n"; + errs().indent(Offset*2) << getPassName() << "\n"; } /// getPassName - Return a nice clean name for a pass. This usually @@ -62,13 +63,13 @@ const char *Pass::getPassName() const { // to print out the contents of an analysis. Otherwise it is not necessary to // implement this method. // -void Pass::print(std::ostream &O,const Module*) const { +void Pass::print(raw_ostream &O,const Module*) const { O << "Pass::print not implemented for pass: '" << getPassName() << "'!\n"; } // dump - call print(cerr); void Pass::dump() const { - print(*cerr.stream(), 0); + print(errs(), 0); } //===----------------------------------------------------------------------===// @@ -128,12 +129,13 @@ class PassRegistrar { /// pass. typedef std::map<intptr_t, const PassInfo*> MapType; MapType PassInfoMap; + + typedef StringMap<const PassInfo*> StringMapType; + StringMapType PassInfoStringMap; /// AnalysisGroupInfo - Keep track of information for each analysis group. struct AnalysisGroupInfo { - const PassInfo *DefaultImpl; std::set<const PassInfo *> Implementations; - AnalysisGroupInfo() : DefaultImpl(0) {} }; /// AnalysisGroupInfoMap - Information for each analysis group. @@ -146,10 +148,16 @@ public: return I != PassInfoMap.end() ? I->second : 0; } + const PassInfo *GetPassInfo(const StringRef &Arg) const { + StringMapType::const_iterator I = PassInfoStringMap.find(Arg); + return I != PassInfoStringMap.end() ? I->second : 0; + } + void RegisterPass(const PassInfo &PI) { bool Inserted = PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second; assert(Inserted && "Pass registered multiple times!"); Inserted=Inserted; + PassInfoStringMap[PI.getPassArgument()] = &PI; } void UnregisterPass(const PassInfo &PI) { @@ -158,6 +166,7 @@ public: // Remove pass from the map. PassInfoMap.erase(I); + PassInfoStringMap.erase(PI.getPassArgument()); } void EnumerateWith(PassRegistrationListener *L) { @@ -176,11 +185,10 @@ public: "Cannot add a pass to the same analysis group more than once!"); AGI.Implementations.insert(ImplementationInfo); if (isDefault) { - assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 && + assert(InterfaceInfo->getNormalCtor() == 0 && "Default implementation for analysis group already specified!"); assert(ImplementationInfo->getNormalCtor() && "Cannot specify pass as default if it does not have a default ctor"); - AGI.DefaultImpl = ImplementationInfo; InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor()); } } @@ -229,11 +237,15 @@ const PassInfo *Pass::lookupPassInfo(intptr_t TI) { return getPassRegistrar()->GetPassInfo(TI); } +const PassInfo *Pass::lookupPassInfo(const StringRef &Arg) { + return getPassRegistrar()->GetPassInfo(Arg); +} + void PassInfo::registerPass() { getPassRegistrar()->RegisterPass(*this); // Notify any listeners. - sys::SmartScopedLock<true> Lock(&ListenersLock); + sys::SmartScopedLock<true> Lock(ListenersLock); if (Listeners) for (std::vector<PassRegistrationListener*>::iterator I = Listeners->begin(), E = Listeners->end(); I != E; ++I) @@ -252,10 +264,10 @@ void PassInfo::unregisterPass() { // RegisterAGBase::RegisterAGBase(const char *Name, intptr_t InterfaceID, intptr_t PassID, bool isDefault) - : PassInfo(Name, InterfaceID), - ImplementationInfo(0), isDefaultImplementation(isDefault) { + : PassInfo(Name, InterfaceID) { - InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(InterfaceID)); + PassInfo *InterfaceInfo = + const_cast<PassInfo*>(Pass::lookupPassInfo(InterfaceID)); if (InterfaceInfo == 0) { // First reference to Interface, register it now. registerPass(); @@ -265,7 +277,7 @@ RegisterAGBase::RegisterAGBase(const char *Name, intptr_t InterfaceID, "Trying to join an analysis group that is a normal pass!"); if (PassID) { - ImplementationInfo = Pass::lookupPassInfo(PassID); + const PassInfo *ImplementationInfo = Pass::lookupPassInfo(PassID); assert(ImplementationInfo && "Must register pass before adding to AnalysisGroup!"); @@ -286,14 +298,14 @@ RegisterAGBase::RegisterAGBase(const char *Name, intptr_t InterfaceID, // PassRegistrationListener ctor - Add the current object to the list of // PassRegistrationListeners... PassRegistrationListener::PassRegistrationListener() { - sys::SmartScopedLock<true> Lock(&ListenersLock); + sys::SmartScopedLock<true> Lock(ListenersLock); if (!Listeners) Listeners = new std::vector<PassRegistrationListener*>(); Listeners->push_back(this); } // dtor - Remove object from list of listeners... PassRegistrationListener::~PassRegistrationListener() { - sys::SmartScopedLock<true> Lock(&ListenersLock); + sys::SmartScopedLock<true> Lock(ListenersLock); std::vector<PassRegistrationListener*>::iterator I = std::find(Listeners->begin(), Listeners->end(), this); assert(Listeners && I != Listeners->end() && diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp index 46f1243e1211..f10bc6f5ef6f 100644 --- a/lib/VMCore/PassManager.cpp +++ b/lib/VMCore/PassManager.cpp @@ -13,16 +13,16 @@ #include "llvm/PassManagers.h" +#include "llvm/Assembly/Writer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Timer.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Mutex.h" #include "llvm/System/Threading.h" -#include "llvm/Analysis/Dominators.h" #include "llvm-c/Core.h" #include <algorithm> #include <cstdio> @@ -45,16 +45,6 @@ enum PassDebugLevel { None, Arguments, Structure, Executions, Details }; -// Always verify dominfo if expensive checking is enabled. -#ifdef XDEBUG -bool VerifyDomInfo = true; -#else -bool VerifyDomInfo = false; -#endif -static cl::opt<bool,true> -VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), - cl::desc("Verify dominator info (time consuming)")); - static cl::opt<enum PassDebugLevel> PassDebugging("debug-pass", cl::Hidden, cl::desc("Print PassManager debugging information"), @@ -67,6 +57,15 @@ PassDebugging("debug-pass", cl::Hidden, clEnumValEnd)); } // End of llvm namespace +/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions +/// or higher is specified. +bool PMDataManager::isPassDebuggingExecutionsOrMore() const { + return PassDebugging >= Executions; +} + + + + void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { if (V == 0 && M == 0) OS << "Releasing pass '"; @@ -134,7 +133,7 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "BasicBlockPass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "BasicBlockPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); BP->dumpPassStructure(Offset + 1); @@ -274,7 +273,7 @@ public: // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "ModulePass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "ModulePass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); MP->dumpPassStructure(Offset + 1); @@ -388,25 +387,19 @@ public: // null. It may be called multiple times. static void createTheTimeInfo(); - void passStarted(Pass *P) { + /// passStarted - This method creates a timer for the given pass if it doesn't + /// already have one, and starts the timer. + Timer *passStarted(Pass *P) { if (dynamic_cast<PMDataManager *>(P)) - return; + return 0; - sys::SmartScopedLock<true> Lock(&*TimingInfoMutex); + sys::SmartScopedLock<true> Lock(*TimingInfoMutex); std::map<Pass*, Timer>::iterator I = TimingData.find(P); if (I == TimingData.end()) I=TimingData.insert(std::make_pair(P, Timer(P->getPassName(), TG))).first; - I->second.startTimer(); - } - - void passEnded(Pass *P) { - if (dynamic_cast<PMDataManager *>(P)) - return; - - sys::SmartScopedLock<true> Lock(&*TimingInfoMutex); - std::map<Pass*, Timer>::iterator I = TimingData.find(P); - assert(I != TimingData.end() && "passStarted/passEnded not nested right!"); - I->second.stopTimer(); + Timer *T = &I->second; + T->startTimer(); + return T; } }; @@ -603,11 +596,11 @@ void PMTopLevelManager::dumpArguments() const { if (PassDebugging < Arguments) return; - cerr << "Pass Arguments: "; + errs() << "Pass Arguments: "; for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(), E = PassManagers.end(); I != E; ++I) (*I)->dumpPassArguments(); - cerr << "\n"; + errs() << "\n"; } void PMTopLevelManager::initializeAllAnalysisInfo() { @@ -700,47 +693,13 @@ void PMDataManager::verifyPreservedAnalysis(Pass *P) { for (AnalysisUsage::VectorType::const_iterator I = PreservedSet.begin(), E = PreservedSet.end(); I != E; ++I) { AnalysisID AID = *I; - if (Pass *AP = findAnalysisPass(AID, true)) - AP->verifyAnalysis(); - } -} - -/// verifyDomInfo - Verify dominator information if it is available. -void PMDataManager::verifyDomInfo(Pass &P, Function &F) { - if (!VerifyDomInfo || !P.getResolver()) - return; - - DominatorTree *DT = P.getAnalysisIfAvailable<DominatorTree>(); - if (!DT) - return; + if (Pass *AP = findAnalysisPass(AID, true)) { - DominatorTree OtherDT; - OtherDT.getBase().recalculate(F); - if (DT->compare(OtherDT)) { - cerr << "Dominator Information for " << F.getNameStart() << "\n"; - cerr << "Pass '" << P.getPassName() << "'\n"; - cerr << "----- Valid -----\n"; - OtherDT.dump(); - cerr << "----- Invalid -----\n"; - DT->dump(); - assert(0 && "Invalid dominator info"); - } - - DominanceFrontier *DF = P.getAnalysisIfAvailable<DominanceFrontier>(); - if (!DF) - return; - - DominanceFrontier OtherDF; - std::vector<BasicBlock*> DTRoots = DT->getRoots(); - OtherDF.calculate(*DT, DT->getNode(DTRoots[0])); - if (DF->compare(OtherDF)) { - cerr << "Dominator Information for " << F.getNameStart() << "\n"; - cerr << "Pass '" << P.getPassName() << "'\n"; - cerr << "----- Valid -----\n"; - OtherDF.dump(); - cerr << "----- Invalid -----\n"; - DF->dump(); - assert(0 && "Invalid dominator info"); + Timer *T = 0; + if (TheTimeInfo) T = TheTimeInfo->passStarted(AP); + AP->verifyAnalysis(); + if (T) T->stopTimer(); + } } } @@ -760,8 +719,8 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { // Remove this analysis if (PassDebugging >= Details) { Pass *S = Info->second; - cerr << " -- '" << P->getPassName() << "' is not preserving '"; - cerr << S->getPassName() << "'\n"; + errs() << " -- '" << P->getPassName() << "' is not preserving '"; + errs() << S->getPassName() << "'\n"; } AvailableAnalysis.erase(Info); } @@ -788,7 +747,7 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) { } /// Remove analysis passes that are not used any longer -void PMDataManager::removeDeadPasses(Pass *P, const char *Msg, +void PMDataManager::removeDeadPasses(Pass *P, const StringRef &Msg, enum PassDebuggingString DBG_STR) { SmallVector<Pass *, 12> DeadPasses; @@ -800,40 +759,41 @@ void PMDataManager::removeDeadPasses(Pass *P, const char *Msg, TPM->collectLastUses(DeadPasses, P); if (PassDebugging >= Details && !DeadPasses.empty()) { - cerr << " -*- '" << P->getPassName(); - cerr << "' is the last user of following pass instances."; - cerr << " Free these instances\n"; + errs() << " -*- '" << P->getPassName(); + errs() << "' is the last user of following pass instances."; + errs() << " Free these instances\n"; } for (SmallVector<Pass *, 12>::iterator I = DeadPasses.begin(), - E = DeadPasses.end(); I != E; ++I) { + E = DeadPasses.end(); I != E; ++I) + freePass(*I, Msg, DBG_STR); +} - dumpPassInfo(*I, FREEING_MSG, DBG_STR, Msg); +void PMDataManager::freePass(Pass *P, const StringRef &Msg, + enum PassDebuggingString DBG_STR) { + dumpPassInfo(P, FREEING_MSG, DBG_STR, Msg); - { - // If the pass crashes releasing memory, remember this. - PassManagerPrettyStackEntry X(*I); - - if (TheTimeInfo) TheTimeInfo->passStarted(*I); - (*I)->releaseMemory(); - if (TheTimeInfo) TheTimeInfo->passEnded(*I); - } - if (const PassInfo *PI = (*I)->getPassInfo()) { - std::map<AnalysisID, Pass*>::iterator Pos = - AvailableAnalysis.find(PI); + { + // If the pass crashes releasing memory, remember this. + PassManagerPrettyStackEntry X(P); + + Timer *T = StartPassTimer(P); + P->releaseMemory(); + StopPassTimer(P, T); + } - // It is possible that pass is already removed from the AvailableAnalysis - if (Pos != AvailableAnalysis.end()) - AvailableAnalysis.erase(Pos); + if (const PassInfo *PI = P->getPassInfo()) { + // Remove the pass itself (if it is not already removed). + AvailableAnalysis.erase(PI); - // Remove all interfaces this pass implements, for which it is also - // listed as the available implementation. - const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) { - Pos = AvailableAnalysis.find(II[i]); - if (Pos != AvailableAnalysis.end() && Pos->second == *I) - AvailableAnalysis.erase(Pos); - } + // Remove all interfaces this pass implements, for which it is also + // listed as the available implementation. + const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) { + std::map<AnalysisID, Pass*>::iterator Pos = + AvailableAnalysis.find(II[i]); + if (Pos != AvailableAnalysis.end() && Pos->second == P) + AvailableAnalysis.erase(Pos); } } } @@ -882,7 +842,7 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { // Keep track of higher level analysis used by this manager. HigherLevelAnalysis.push_back(PRequired); } else - assert(0 && "Unable to accomodate Required Pass"); + llvm_unreachable("Unable to accomodate Required Pass"); } // Set P as P's last user until someone starts using P. @@ -994,7 +954,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{ for (SmallVector<Pass *, 12>::iterator I = LUses.begin(), E = LUses.end(); I != E; ++I) { - llvm::cerr << "--" << std::string(Offset*2, ' '); + llvm::errs() << "--" << std::string(Offset*2, ' '); (*I)->dumpPassStructure(0); } } @@ -1007,44 +967,44 @@ void PMDataManager::dumpPassArguments() const { else if (const PassInfo *PI = (*I)->getPassInfo()) if (!PI->isAnalysisGroup()) - cerr << " -" << PI->getPassArgument(); + errs() << " -" << PI->getPassArgument(); } } void PMDataManager::dumpPassInfo(Pass *P, enum PassDebuggingString S1, enum PassDebuggingString S2, - const char *Msg) { + const StringRef &Msg) { if (PassDebugging < Executions) return; - cerr << (void*)this << std::string(getDepth()*2+1, ' '); + errs() << (void*)this << std::string(getDepth()*2+1, ' '); switch (S1) { case EXECUTION_MSG: - cerr << "Executing Pass '" << P->getPassName(); + errs() << "Executing Pass '" << P->getPassName(); break; case MODIFICATION_MSG: - cerr << "Made Modification '" << P->getPassName(); + errs() << "Made Modification '" << P->getPassName(); break; case FREEING_MSG: - cerr << " Freeing Pass '" << P->getPassName(); + errs() << " Freeing Pass '" << P->getPassName(); break; default: break; } switch (S2) { case ON_BASICBLOCK_MSG: - cerr << "' on BasicBlock '" << Msg << "'...\n"; + errs() << "' on BasicBlock '" << Msg << "'...\n"; break; case ON_FUNCTION_MSG: - cerr << "' on Function '" << Msg << "'...\n"; + errs() << "' on Function '" << Msg << "'...\n"; break; case ON_MODULE_MSG: - cerr << "' on Module '" << Msg << "'...\n"; + errs() << "' on Module '" << Msg << "'...\n"; break; case ON_LOOP_MSG: - cerr << "' on Loop " << Msg << "'...\n"; + errs() << "' on Loop '" << Msg << "'...\n"; break; case ON_CG_MSG: - cerr << "' on Call Graph " << Msg << "'...\n"; + errs() << "' on Call Graph Nodes '" << Msg << "'...\n"; break; default: break; @@ -1069,17 +1029,17 @@ void PMDataManager::dumpPreservedSet(const Pass *P) const { dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); } -void PMDataManager::dumpAnalysisUsage(const char *Msg, const Pass *P, +void PMDataManager::dumpAnalysisUsage(const StringRef &Msg, const Pass *P, const AnalysisUsage::VectorType &Set) const { assert(PassDebugging >= Details); if (Set.empty()) return; - cerr << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; + errs() << (void*)P << std::string(getDepth()*2+3, ' ') << Msg << " Analyses:"; for (unsigned i = 0; i != Set.size(); ++i) { - if (i) cerr << ","; - cerr << " " << Set[i]->getPassName(); + if (i) errs() << ','; + errs() << ' ' << Set[i]->getPassName(); } - cerr << "\n"; + errs() << '\n'; } /// Add RequiredPass into list of lower level passes required by pass P. @@ -1102,10 +1062,10 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) { // checks whether any lower level manager will be able to provide this // analysis info on demand or not. #ifndef NDEBUG - cerr << "Unable to schedule '" << RequiredPass->getPassName(); - cerr << "' required by '" << P->getPassName() << "'\n"; + errs() << "Unable to schedule '" << RequiredPass->getPassName(); + errs() << "' required by '" << P->getPassName() << "'\n"; #endif - assert(0 && "Unable to schedule pass"); + llvm_unreachable("Unable to schedule pass"); } // Destructor @@ -1143,7 +1103,7 @@ bool BBPassManager::runOnFunction(Function &F) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); - dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getNameStart()); + dumpPassInfo(BP, EXECUTION_MSG, ON_BASICBLOCK_MSG, I->getName()); dumpRequiredSet(BP); initializeAnalysisImpl(BP); @@ -1152,20 +1112,20 @@ bool BBPassManager::runOnFunction(Function &F) { // If the pass crashes, remember this. PassManagerPrettyStackEntry X(BP, *I); - if (TheTimeInfo) TheTimeInfo->passStarted(BP); + Timer *T = StartPassTimer(BP); Changed |= BP->runOnBasicBlock(*I); - if (TheTimeInfo) TheTimeInfo->passEnded(BP); + StopPassTimer(BP, T); } if (Changed) dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, - I->getNameStart()); + I->getName()); dumpPreservedSet(BP); verifyPreservedAnalysis(BP); removeNotPreservedAnalysis(BP); recordAvailableAnalysis(BP); - removeDeadPasses(BP, I->getNameStart(), ON_BASICBLOCK_MSG); + removeDeadPasses(BP, I->getName(), ON_BASICBLOCK_MSG); } return Changed |= doFinalization(F); @@ -1248,8 +1208,7 @@ void FunctionPassManager::add(Pass *P) { bool FunctionPassManager::run(Function &F) { std::string errstr; if (MP->materializeFunction(&F, &errstr)) { - cerr << "Error reading bitcode file: " << errstr << "\n"; - abort(); + llvm_report_error("Error reading bitcode file: " + errstr); } return FPM->run(F); } @@ -1336,7 +1295,7 @@ bool FunctionPassManagerImpl::run(Function &F) { char FPPassManager::ID = 0; /// Print passes managed by this manager void FPPassManager::dumpPassStructure(unsigned Offset) { - llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; + llvm::errs() << std::string(Offset*2, ' ') << "FunctionPass Manager\n"; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); FP->dumpPassStructure(Offset + 1); @@ -1360,7 +1319,7 @@ bool FPPassManager::runOnFunction(Function &F) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); - dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getNameStart()); + dumpPassInfo(FP, EXECUTION_MSG, ON_FUNCTION_MSG, F.getName()); dumpRequiredSet(FP); initializeAnalysisImpl(FP); @@ -1368,22 +1327,19 @@ bool FPPassManager::runOnFunction(Function &F) { { PassManagerPrettyStackEntry X(FP, F); - if (TheTimeInfo) TheTimeInfo->passStarted(FP); + Timer *T = StartPassTimer(FP); Changed |= FP->runOnFunction(F); - if (TheTimeInfo) TheTimeInfo->passEnded(FP); + StopPassTimer(FP, T); } if (Changed) - dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getNameStart()); + dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); dumpPreservedSet(FP); verifyPreservedAnalysis(FP); removeNotPreservedAnalysis(FP); recordAvailableAnalysis(FP); - removeDeadPasses(FP, F.getNameStart(), ON_FUNCTION_MSG); - - // If dominator information is available then verify the info if requested. - verifyDomInfo(*FP, F); + removeDeadPasses(FP, F.getName(), ON_FUNCTION_MSG); } return Changed; } @@ -1444,9 +1400,9 @@ MPPassManager::runOnModule(Module &M) { { PassManagerPrettyStackEntry X(MP, M); - if (TheTimeInfo) TheTimeInfo->passStarted(MP); + Timer *T = StartPassTimer(MP); Changed |= MP->runOnModule(M); - if (TheTimeInfo) TheTimeInfo->passEnded(MP); + StopPassTimer(MP, T); } if (Changed) @@ -1582,15 +1538,15 @@ void TimingInfo::createTheTimeInfo() { } /// If TimingInfo is enabled then start pass timer. -void StartPassTimer(Pass *P) { +Timer *llvm::StartPassTimer(Pass *P) { if (TheTimeInfo) - TheTimeInfo->passStarted(P); + return TheTimeInfo->passStarted(P); + return 0; } /// If TimingInfo is enabled then stop pass timer. -void StopPassTimer(Pass *P) { - if (TheTimeInfo) - TheTimeInfo->passEnded(P); +void llvm::StopPassTimer(Pass *P, Timer *T) { + if (T) T->stopTimer(); } //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 40d751704917..7afbc682d15d 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -11,15 +11,19 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" #include "llvm/Assembly/Writer.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/SCCIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -38,26 +42,14 @@ using namespace llvm; AbstractTypeUser::~AbstractTypeUser() {} +void AbstractTypeUser::setType(Value *V, const Type *NewTy) { + V->VTy = NewTy; +} //===----------------------------------------------------------------------===// // Type Class Implementation //===----------------------------------------------------------------------===// -// Lock used for guarding access to the type maps. -static ManagedStatic<sys::SmartMutex<true> > TypeMapLock; - -// Recursive lock used for guarding access to AbstractTypeUsers. -// NOTE: The true template parameter means this will no-op when we're not in -// multithreaded mode. -static ManagedStatic<sys::SmartMutex<true> > AbstractTypeUsersLock; - -// Concrete/Abstract TypeDescriptions - We lazily calculate type descriptions -// for types as they are needed. Because resolution of types must invalidate -// all of the abstract type descriptions, we keep them in a seperate map to make -// this easy. -static ManagedStatic<TypePrinting> ConcreteTypeDescriptions; -static ManagedStatic<TypePrinting> AbstractTypeDescriptions; - /// Because of the way Type subclasses are allocated, this function is necessary /// to use the correct kind of "delete" operator to deallocate the Type object. /// Some type objects (FunctionTy, StructTy) allocate additional space after @@ -99,26 +91,26 @@ void Type::destroy() const { delete this; } -const Type *Type::getPrimitiveType(TypeID IDNumber) { +const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { switch (IDNumber) { - case VoidTyID : return VoidTy; - case FloatTyID : return FloatTy; - case DoubleTyID : return DoubleTy; - case X86_FP80TyID : return X86_FP80Ty; - case FP128TyID : return FP128Ty; - case PPC_FP128TyID : return PPC_FP128Ty; - case LabelTyID : return LabelTy; - case MetadataTyID : return MetadataTy; + case VoidTyID : return getVoidTy(C); + case FloatTyID : return getFloatTy(C); + case DoubleTyID : return getDoubleTy(C); + case X86_FP80TyID : return getX86_FP80Ty(C); + case FP128TyID : return getFP128Ty(C); + case PPC_FP128TyID : return getPPC_FP128Ty(C); + case LabelTyID : return getLabelTy(C); + case MetadataTyID : return getMetadataTy(C); default: return 0; } } -const Type *Type::getVAArgsPromotedType() const { +const Type *Type::getVAArgsPromotedType(LLVMContext &C) const { if (ID == IntegerTyID && getSubclassData() < 32) - return Type::Int32Ty; + return Type::getInt32Ty(C); else if (ID == FloatTyID) - return Type::DoubleTy; + return Type::getDoubleTy(C); else return this; } @@ -264,16 +256,19 @@ const Type *Type::getForwardedTypeInternal() const { } void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - abort(); + llvm_unreachable("Attempting to refine a derived type!"); } void Type::typeBecameConcrete(const DerivedType *AbsTy) { - abort(); + llvm_unreachable("DerivedType is already a concrete type!"); } std::string Type::getDescription() const { + LLVMContextImpl *pImpl = getContext().pImpl; TypePrinting &Map = - isAbstract() ? *AbstractTypeDescriptions : *ConcreteTypeDescriptions; + isAbstract() ? + pImpl->AbstractTypeDescriptions : + pImpl->ConcreteTypeDescriptions; std::string DescStr; raw_string_ostream DescOS(DescStr); @@ -284,7 +279,7 @@ std::string Type::getDescription() const { bool StructType::indexValid(const Value *V) const { // Structure indexes require 32-bit integer constants. - if (V->getType() == Type::Int32Ty) + if (V->getType() == Type::getInt32Ty(V->getContext())) if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) return indexValid(CU->getZExtValue()); return false; @@ -311,25 +306,97 @@ const Type *StructType::getTypeAtIndex(unsigned Idx) const { // Primitive 'Type' data //===----------------------------------------------------------------------===// -const Type *Type::VoidTy = new Type(Type::VoidTyID); -const Type *Type::FloatTy = new Type(Type::FloatTyID); -const Type *Type::DoubleTy = new Type(Type::DoubleTyID); -const Type *Type::X86_FP80Ty = new Type(Type::X86_FP80TyID); -const Type *Type::FP128Ty = new Type(Type::FP128TyID); -const Type *Type::PPC_FP128Ty = new Type(Type::PPC_FP128TyID); -const Type *Type::LabelTy = new Type(Type::LabelTyID); -const Type *Type::MetadataTy = new Type(Type::MetadataTyID); +const Type *Type::getVoidTy(LLVMContext &C) { + return &C.pImpl->VoidTy; +} -namespace { - struct BuiltinIntegerType : public IntegerType { - explicit BuiltinIntegerType(unsigned W) : IntegerType(W) {} - }; +const Type *Type::getLabelTy(LLVMContext &C) { + return &C.pImpl->LabelTy; +} + +const Type *Type::getFloatTy(LLVMContext &C) { + return &C.pImpl->FloatTy; +} + +const Type *Type::getDoubleTy(LLVMContext &C) { + return &C.pImpl->DoubleTy; +} + +const Type *Type::getMetadataTy(LLVMContext &C) { + return &C.pImpl->MetadataTy; +} + +const Type *Type::getX86_FP80Ty(LLVMContext &C) { + return &C.pImpl->X86_FP80Ty; +} + +const Type *Type::getFP128Ty(LLVMContext &C) { + return &C.pImpl->FP128Ty; +} + +const Type *Type::getPPC_FP128Ty(LLVMContext &C) { + return &C.pImpl->PPC_FP128Ty; +} + +const IntegerType *Type::getInt1Ty(LLVMContext &C) { + return &C.pImpl->Int1Ty; +} + +const IntegerType *Type::getInt8Ty(LLVMContext &C) { + return &C.pImpl->Int8Ty; +} + +const IntegerType *Type::getInt16Ty(LLVMContext &C) { + return &C.pImpl->Int16Ty; +} + +const IntegerType *Type::getInt32Ty(LLVMContext &C) { + return &C.pImpl->Int32Ty; +} + +const IntegerType *Type::getInt64Ty(LLVMContext &C) { + return &C.pImpl->Int64Ty; +} + +const PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) { + return getFloatTy(C)->getPointerTo(AS); +} + +const PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) { + return getDoubleTy(C)->getPointerTo(AS); +} + +const PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) { + return getX86_FP80Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) { + return getFP128Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { + return getPPC_FP128Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) { + return getInt1Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) { + return getInt8Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) { + return getInt16Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) { + return getInt32Ty(C)->getPointerTo(AS); +} + +const PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) { + return getInt64Ty(C)->getPointerTo(AS); } -const IntegerType *Type::Int1Ty = new BuiltinIntegerType(1); -const IntegerType *Type::Int8Ty = new BuiltinIntegerType(8); -const IntegerType *Type::Int16Ty = new BuiltinIntegerType(16); -const IntegerType *Type::Int32Ty = new BuiltinIntegerType(32); -const IntegerType *Type::Int64Ty = new BuiltinIntegerType(64); //===----------------------------------------------------------------------===// // Derived Type Constructors @@ -338,42 +405,20 @@ const IntegerType *Type::Int64Ty = new BuiltinIntegerType(64); /// isValidReturnType - Return true if the specified type is valid as a return /// type. bool FunctionType::isValidReturnType(const Type *RetTy) { - if (RetTy->isFirstClassType()) { - if (const PointerType *PTy = dyn_cast<PointerType>(RetTy)) - return PTy->getElementType() != Type::MetadataTy; - return true; - } - if (RetTy == Type::VoidTy || RetTy == Type::MetadataTy || - isa<OpaqueType>(RetTy)) - return true; - - // If this is a multiple return case, verify that each return is a first class - // value and that there is at least one value. - const StructType *SRetTy = dyn_cast<StructType>(RetTy); - if (SRetTy == 0 || SRetTy->getNumElements() == 0) - return false; - - for (unsigned i = 0, e = SRetTy->getNumElements(); i != e; ++i) - if (!SRetTy->getElementType(i)->isFirstClassType()) - return false; - return true; + return RetTy->getTypeID() != LabelTyID && + RetTy->getTypeID() != MetadataTyID; } /// isValidArgumentType - Return true if the specified type is valid as an /// argument type. bool FunctionType::isValidArgumentType(const Type *ArgTy) { - if ((!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy)) || - (isa<PointerType>(ArgTy) && - cast<PointerType>(ArgTy)->getElementType() == Type::MetadataTy)) - return false; - - return true; + return ArgTy->isFirstClassType() || isa<OpaqueType>(ArgTy); } FunctionType::FunctionType(const Type *Result, const std::vector<const Type*> &Params, bool IsVarArgs) - : DerivedType(FunctionTyID), isVarArgs(IsVarArgs) { + : DerivedType(Result->getContext(), FunctionTyID), isVarArgs(IsVarArgs) { ContainedTys = reinterpret_cast<PATypeHandle*>(this+1); NumContainedTys = Params.size() + 1; // + 1 for result type assert(isValidReturnType(Result) && "invalid return type for function"); @@ -393,8 +438,9 @@ FunctionType::FunctionType(const Type *Result, setAbstract(isAbstract); } -StructType::StructType(const std::vector<const Type*> &Types, bool isPacked) - : CompositeType(StructTyID) { +StructType::StructType(LLVMContext &C, + const std::vector<const Type*> &Types, bool isPacked) + : CompositeType(C, StructTyID) { ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1); NumContainedTys = Types.size(); setSubclassData(isPacked); @@ -437,10 +483,10 @@ PointerType::PointerType(const Type *E, unsigned AddrSpace) setAbstract(E->isAbstract()); } -OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) { +OpaqueType::OpaqueType(LLVMContext &C) : DerivedType(C, OpaqueTyID) { setAbstract(true); #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *this << "\n"; + DEBUG(errs() << "Derived new type: " << *this << "\n"); #endif } @@ -464,8 +510,8 @@ void DerivedType::dropAllTypeUses() { llvm_acquire_global_lock(); tmp = AlwaysOpaqueTy; if (!tmp) { - tmp = OpaqueType::get(); - PATypeHolder* tmp2 = new PATypeHolder(AlwaysOpaqueTy); + tmp = OpaqueType::get(getContext()); + PATypeHolder* tmp2 = new PATypeHolder(tmp); sys::MemoryFence(); AlwaysOpaqueTy = tmp; Holder = tmp2; @@ -473,8 +519,8 @@ void DerivedType::dropAllTypeUses() { llvm_release_global_lock(); } - } else { - AlwaysOpaqueTy = OpaqueType::get(); + } else if (!AlwaysOpaqueTy) { + AlwaysOpaqueTy = OpaqueType::get(getContext()); Holder = new PATypeHolder(AlwaysOpaqueTy); } @@ -482,9 +528,11 @@ void DerivedType::dropAllTypeUses() { // Change the rest of the types to be Int32Ty's. It doesn't matter what we // pick so long as it doesn't point back to this type. We choose something - // concrete to avoid overhead for adding to AbstracTypeUser lists and stuff. + // concrete to avoid overhead for adding to AbstractTypeUser lists and + // stuff. + const Type *ConcreteTy = Type::getInt32Ty(getContext()); for (unsigned i = 1, e = NumContainedTys; i != e; ++i) - ContainedTys[i] = Type::Int32Ty; + ContainedTys[i] = ConcreteTy; } } @@ -633,7 +681,7 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2, } return true; } else { - assert(0 && "Unknown derived type!"); + llvm_unreachable("Unknown derived type!"); return false; } } @@ -695,327 +743,41 @@ static bool TypeHasCycleThroughItself(const Type *Ty) { return false; } -/// getSubElementHash - Generate a hash value for all of the SubType's of this -/// type. The hash value is guaranteed to be zero if any of the subtypes are -/// an opaque type. Otherwise we try to mix them in as well as possible, but do -/// not look at the subtype's subtype's. -static unsigned getSubElementHash(const Type *Ty) { - unsigned HashVal = 0; - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) { - HashVal *= 32; - const Type *SubTy = I->get(); - HashVal += SubTy->getTypeID(); - switch (SubTy->getTypeID()) { - default: break; - case Type::OpaqueTyID: return 0; // Opaque -> hash = 0 no matter what. - case Type::IntegerTyID: - HashVal ^= (cast<IntegerType>(SubTy)->getBitWidth() << 3); - break; - case Type::FunctionTyID: - HashVal ^= cast<FunctionType>(SubTy)->getNumParams()*2 + - cast<FunctionType>(SubTy)->isVarArg(); - break; - case Type::ArrayTyID: - HashVal ^= cast<ArrayType>(SubTy)->getNumElements(); - break; - case Type::VectorTyID: - HashVal ^= cast<VectorType>(SubTy)->getNumElements(); - break; - case Type::StructTyID: - HashVal ^= cast<StructType>(SubTy)->getNumElements(); - break; - case Type::PointerTyID: - HashVal ^= cast<PointerType>(SubTy)->getAddressSpace(); - break; - } - } - return HashVal ? HashVal : 1; // Do not return zero unless opaque subty. -} - -//===----------------------------------------------------------------------===// -// Derived Type Factory Functions -//===----------------------------------------------------------------------===// - -namespace llvm { -class TypeMapBase { -protected: - /// TypesByHash - Keep track of types by their structure hash value. Note - /// that we only keep track of types that have cycles through themselves in - /// this map. - /// - std::multimap<unsigned, PATypeHolder> TypesByHash; - -public: - ~TypeMapBase() { - // PATypeHolder won't destroy non-abstract types. - // We can't destroy them by simply iterating, because - // they may contain references to each-other. -#if 0 - for (std::multimap<unsigned, PATypeHolder>::iterator I - = TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) { - Type *Ty = const_cast<Type*>(I->second.Ty); - I->second.destroy(); - // We can't invoke destroy or delete, because the type may - // contain references to already freed types. - // So we have to destruct the object the ugly way. - if (Ty) { - Ty->AbstractTypeUsers.clear(); - static_cast<const Type*>(Ty)->Type::~Type(); - operator delete(Ty); - } - } -#endif - } - - void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { - std::multimap<unsigned, PATypeHolder>::iterator I = - TypesByHash.lower_bound(Hash); - for (; I != TypesByHash.end() && I->first == Hash; ++I) { - if (I->second == Ty) { - TypesByHash.erase(I); - return; - } - } - - // This must be do to an opaque type that was resolved. Switch down to hash - // code of zero. - assert(Hash && "Didn't find type entry!"); - RemoveFromTypesByHash(0, Ty); - } - - /// TypeBecameConcrete - When Ty gets a notification that TheType just became - /// concrete, drop uses and make Ty non-abstract if we should. - void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) { - // If the element just became concrete, remove 'ty' from the abstract - // type user list for the type. Do this for as many times as Ty uses - // OldType. - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (I->get() == TheType) - TheType->removeAbstractTypeUser(Ty); - - // If the type is currently thought to be abstract, rescan all of our - // subtypes to see if the type has just become concrete! Note that this - // may send out notifications to AbstractTypeUsers that types become - // concrete. - if (Ty->isAbstract()) - Ty->PromoteAbstractToConcrete(); - } -}; -} - - -// TypeMap - Make sure that only one instance of a particular type may be -// created on any given run of the compiler... note that this involves updating -// our map if an abstract type gets refined somehow. -// -namespace llvm { -template<class ValType, class TypeClass> -class TypeMap : public TypeMapBase { - std::map<ValType, PATypeHolder> Map; -public: - typedef typename std::map<ValType, PATypeHolder>::iterator iterator; - ~TypeMap() { print("ON EXIT"); } - - inline TypeClass *get(const ValType &V) { - iterator I = Map.find(V); - return I != Map.end() ? cast<TypeClass>((Type*)I->second.get()) : 0; - } - - inline void add(const ValType &V, TypeClass *Ty) { - Map.insert(std::make_pair(V, Ty)); - - // If this type has a cycle, remember it. - TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty)); - print("add"); - } - - /// RefineAbstractType - This method is called after we have merged a type - /// with another one. We must now either merge the type away with - /// some other type or reinstall it in the map with it's new configuration. - void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType, - const Type *NewType) { -#ifdef DEBUG_MERGE_TYPES - DOUT << "RefineAbstractType(" << (void*)OldType << "[" << *OldType - << "], " << (void*)NewType << " [" << *NewType << "])\n"; -#endif - - // Otherwise, we are changing one subelement type into another. Clearly the - // OldType must have been abstract, making us abstract. - assert(Ty->isAbstract() && "Refining a non-abstract type!"); - assert(OldType != NewType); - - // Make a temporary type holder for the type so that it doesn't disappear on - // us when we erase the entry from the map. - PATypeHolder TyHolder = Ty; - - // The old record is now out-of-date, because one of the children has been - // updated. Remove the obsolete entry from the map. - unsigned NumErased = Map.erase(ValType::get(Ty)); - assert(NumErased && "Element not found!"); NumErased = NumErased; - - // Remember the structural hash for the type before we start hacking on it, - // in case we need it later. - unsigned OldTypeHash = ValType::hashTypeStructure(Ty); - - // Find the type element we are refining... and change it now! - for (unsigned i = 0, e = Ty->getNumContainedTypes(); i != e; ++i) - if (Ty->ContainedTys[i] == OldType) - Ty->ContainedTys[i] = NewType; - unsigned NewTypeHash = ValType::hashTypeStructure(Ty); - - // If there are no cycles going through this node, we can do a simple, - // efficient lookup in the map, instead of an inefficient nasty linear - // lookup. - if (!TypeHasCycleThroughItself(Ty)) { - typename std::map<ValType, PATypeHolder>::iterator I; - bool Inserted; - - tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty)); - if (!Inserted) { - // Refined to a different type altogether? - RemoveFromTypesByHash(OldTypeHash, Ty); - - // We already have this type in the table. Get rid of the newly refined - // type. - TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); - Ty->unlockedRefineAbstractTypeTo(NewTy); - return; - } - } else { - // Now we check to see if there is an existing entry in the table which is - // structurally identical to the newly refined type. If so, this type - // gets refined to the pre-existing type. - // - std::multimap<unsigned, PATypeHolder>::iterator I, E, Entry; - tie(I, E) = TypesByHash.equal_range(NewTypeHash); - Entry = E; - for (; I != E; ++I) { - if (I->second == Ty) { - // Remember the position of the old type if we see it in our scan. - Entry = I; - } else { - if (TypesEqual(Ty, I->second)) { - TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); - - // Remove the old entry form TypesByHash. If the hash values differ - // now, remove it from the old place. Otherwise, continue scanning - // withing this hashcode to reduce work. - if (NewTypeHash != OldTypeHash) { - RemoveFromTypesByHash(OldTypeHash, Ty); - } else { - if (Entry == E) { - // Find the location of Ty in the TypesByHash structure if we - // haven't seen it already. - while (I->second != Ty) { - ++I; - assert(I != E && "Structure doesn't contain type??"); - } - Entry = I; - } - TypesByHash.erase(Entry); - } - Ty->unlockedRefineAbstractTypeTo(NewTy); - return; - } - } - } - - // If there is no existing type of the same structure, we reinsert an - // updated record into the map. - Map.insert(std::make_pair(ValType::get(Ty), Ty)); - } - - // If the hash codes differ, update TypesByHash - if (NewTypeHash != OldTypeHash) { - RemoveFromTypesByHash(OldTypeHash, Ty); - TypesByHash.insert(std::make_pair(NewTypeHash, Ty)); - } - - // If the type is currently thought to be abstract, rescan all of our - // subtypes to see if the type has just become concrete! Note that this - // may send out notifications to AbstractTypeUsers that types become - // concrete. - if (Ty->isAbstract()) - Ty->PromoteAbstractToConcrete(); - } - - void print(const char *Arg) const { -#ifdef DEBUG_MERGE_TYPES - DOUT << "TypeMap<>::" << Arg << " table contents:\n"; - unsigned i = 0; - for (typename std::map<ValType, PATypeHolder>::const_iterator I - = Map.begin(), E = Map.end(); I != E; ++I) - DOUT << " " << (++i) << ". " << (void*)I->second.get() << " " - << *I->second.get() << "\n"; -#endif - } - - void dump() const { print("dump output"); } -}; -} - - //===----------------------------------------------------------------------===// // Function Type Factory and Value Class... // - -//===----------------------------------------------------------------------===// -// Integer Type Factory... -// -namespace llvm { -class IntegerValType { - uint32_t bits; -public: - IntegerValType(uint16_t numbits) : bits(numbits) {} - - static IntegerValType get(const IntegerType *Ty) { - return IntegerValType(Ty->getBitWidth()); - } - - static unsigned hashTypeStructure(const IntegerType *Ty) { - return (unsigned)Ty->getBitWidth(); - } - - inline bool operator<(const IntegerValType &IVT) const { - return bits < IVT.bits; - } -}; -} - -static ManagedStatic<TypeMap<IntegerValType, IntegerType> > IntegerTypes; - -const IntegerType *IntegerType::get(unsigned NumBits) { +const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { assert(NumBits >= MIN_INT_BITS && "bitwidth too small"); assert(NumBits <= MAX_INT_BITS && "bitwidth too large"); // Check for the built-in integer types switch (NumBits) { - case 1: return cast<IntegerType>(Type::Int1Ty); - case 8: return cast<IntegerType>(Type::Int8Ty); - case 16: return cast<IntegerType>(Type::Int16Ty); - case 32: return cast<IntegerType>(Type::Int32Ty); - case 64: return cast<IntegerType>(Type::Int64Ty); + case 1: return cast<IntegerType>(Type::getInt1Ty(C)); + case 8: return cast<IntegerType>(Type::getInt8Ty(C)); + case 16: return cast<IntegerType>(Type::getInt16Ty(C)); + case 32: return cast<IntegerType>(Type::getInt32Ty(C)); + case 64: return cast<IntegerType>(Type::getInt64Ty(C)); default: break; } + + LLVMContextImpl *pImpl = C.pImpl; IntegerValType IVT(NumBits); IntegerType *ITy = 0; // First, see if the type is already in the table, for which // a reader lock suffices. - sys::SmartScopedLock<true> L(&*TypeMapLock); - ITy = IntegerTypes->get(IVT); + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + ITy = pImpl->IntegerTypes.get(IVT); if (!ITy) { // Value not found. Derive a new type! - ITy = new IntegerType(NumBits); - IntegerTypes->add(IVT, ITy); + ITy = new IntegerType(C, NumBits); + pImpl->IntegerTypes.add(IVT, ITy); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *ITy << "\n"; + DEBUG(errs() << "Derived new type: " << *ITy << "\n"); #endif return ITy; } @@ -1029,39 +791,6 @@ APInt IntegerType::getMask() const { return APInt::getAllOnesValue(getBitWidth()); } -// FunctionValType - Define a class to hold the key that goes into the TypeMap -// -namespace llvm { -class FunctionValType { - const Type *RetTy; - std::vector<const Type*> ArgTypes; - bool isVarArg; -public: - FunctionValType(const Type *ret, const std::vector<const Type*> &args, - bool isVA) : RetTy(ret), ArgTypes(args), isVarArg(isVA) {} - - static FunctionValType get(const FunctionType *FT); - - static unsigned hashTypeStructure(const FunctionType *FT) { - unsigned Result = FT->getNumParams()*2 + FT->isVarArg(); - return Result; - } - - inline bool operator<(const FunctionValType &MTV) const { - if (RetTy < MTV.RetTy) return true; - if (RetTy > MTV.RetTy) return false; - if (isVarArg < MTV.isVarArg) return true; - if (isVarArg > MTV.isVarArg) return false; - if (ArgTypes < MTV.ArgTypes) return true; - if (ArgTypes > MTV.ArgTypes) return false; - return false; - } -}; -} - -// Define the actual map itself now... -static ManagedStatic<TypeMap<FunctionValType, FunctionType> > FunctionTypes; - FunctionValType FunctionValType::get(const FunctionType *FT) { // Build up a FunctionValType std::vector<const Type *> ParamTypes; @@ -1079,194 +808,105 @@ FunctionType *FunctionType::get(const Type *ReturnType, FunctionValType VT(ReturnType, Params, isVarArg); FunctionType *FT = 0; - sys::SmartScopedLock<true> L(&*TypeMapLock); - FT = FunctionTypes->get(VT); + LLVMContextImpl *pImpl = ReturnType->getContext().pImpl; + + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + FT = pImpl->FunctionTypes.get(VT); if (!FT) { FT = (FunctionType*) operator new(sizeof(FunctionType) + sizeof(PATypeHandle)*(Params.size()+1)); new (FT) FunctionType(ReturnType, Params, isVarArg); - FunctionTypes->add(VT, FT); + pImpl->FunctionTypes.add(VT, FT); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << FT << "\n"; + DEBUG(errs() << "Derived new type: " << FT << "\n"); #endif return FT; } -//===----------------------------------------------------------------------===// -// Array Type Factory... -// -namespace llvm { -class ArrayValType { - const Type *ValTy; - uint64_t Size; -public: - ArrayValType(const Type *val, uint64_t sz) : ValTy(val), Size(sz) {} - - static ArrayValType get(const ArrayType *AT) { - return ArrayValType(AT->getElementType(), AT->getNumElements()); - } - - static unsigned hashTypeStructure(const ArrayType *AT) { - return (unsigned)AT->getNumElements(); - } - - inline bool operator<(const ArrayValType &MTV) const { - if (Size < MTV.Size) return true; - return Size == MTV.Size && ValTy < MTV.ValTy; - } -}; -} - -static ManagedStatic<TypeMap<ArrayValType, ArrayType> > ArrayTypes; - ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) { assert(ElementType && "Can't get array of <null> types!"); assert(isValidElementType(ElementType) && "Invalid type for array element!"); ArrayValType AVT(ElementType, NumElements); ArrayType *AT = 0; + + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; - sys::SmartScopedLock<true> L(&*TypeMapLock); - AT = ArrayTypes->get(AVT); + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + AT = pImpl->ArrayTypes.get(AVT); if (!AT) { // Value not found. Derive a new type! - ArrayTypes->add(AVT, AT = new ArrayType(ElementType, NumElements)); + pImpl->ArrayTypes.add(AVT, AT = new ArrayType(ElementType, NumElements)); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *AT << "\n"; + DEBUG(errs() << "Derived new type: " << *AT << "\n"); #endif return AT; } bool ArrayType::isValidElementType(const Type *ElemTy) { - if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy || - ElemTy == Type::MetadataTy) - return false; - - if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy)) - if (PTy->getElementType() == Type::MetadataTy) - return false; - - return true; + return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID && + ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy); } - -//===----------------------------------------------------------------------===// -// Vector Type Factory... -// -namespace llvm { -class VectorValType { - const Type *ValTy; - unsigned Size; -public: - VectorValType(const Type *val, int sz) : ValTy(val), Size(sz) {} - - static VectorValType get(const VectorType *PT) { - return VectorValType(PT->getElementType(), PT->getNumElements()); - } - - static unsigned hashTypeStructure(const VectorType *PT) { - return PT->getNumElements(); - } - - inline bool operator<(const VectorValType &MTV) const { - if (Size < MTV.Size) return true; - return Size == MTV.Size && ValTy < MTV.ValTy; - } -}; -} - -static ManagedStatic<TypeMap<VectorValType, VectorType> > VectorTypes; - VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) { assert(ElementType && "Can't get vector of <null> types!"); VectorValType PVT(ElementType, NumElements); VectorType *PT = 0; - sys::SmartScopedLock<true> L(&*TypeMapLock); - PT = VectorTypes->get(PVT); + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; + + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + PT = pImpl->VectorTypes.get(PVT); if (!PT) { - VectorTypes->add(PVT, PT = new VectorType(ElementType, NumElements)); + pImpl->VectorTypes.add(PVT, PT = new VectorType(ElementType, NumElements)); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *PT << "\n"; + DEBUG(errs() << "Derived new type: " << *PT << "\n"); #endif return PT; } bool VectorType::isValidElementType(const Type *ElemTy) { - if (ElemTy->isInteger() || ElemTy->isFloatingPoint() || - isa<OpaqueType>(ElemTy)) - return true; - - return false; + return ElemTy->isInteger() || ElemTy->isFloatingPoint() || + isa<OpaqueType>(ElemTy); } //===----------------------------------------------------------------------===// // Struct Type Factory... // -namespace llvm { -// StructValType - Define a class to hold the key that goes into the TypeMap -// -class StructValType { - std::vector<const Type*> ElTypes; - bool packed; -public: - StructValType(const std::vector<const Type*> &args, bool isPacked) - : ElTypes(args), packed(isPacked) {} - - static StructValType get(const StructType *ST) { - std::vector<const Type *> ElTypes; - ElTypes.reserve(ST->getNumElements()); - for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) - ElTypes.push_back(ST->getElementType(i)); - - return StructValType(ElTypes, ST->isPacked()); - } - - static unsigned hashTypeStructure(const StructType *ST) { - return ST->getNumElements(); - } - - inline bool operator<(const StructValType &STV) const { - if (ElTypes < STV.ElTypes) return true; - else if (ElTypes > STV.ElTypes) return false; - else return (int)packed < (int)STV.packed; - } -}; -} - -static ManagedStatic<TypeMap<StructValType, StructType> > StructTypes; - -StructType *StructType::get(const std::vector<const Type*> &ETypes, +StructType *StructType::get(LLVMContext &Context, + const std::vector<const Type*> &ETypes, bool isPacked) { StructValType STV(ETypes, isPacked); StructType *ST = 0; - sys::SmartScopedLock<true> L(&*TypeMapLock); - ST = StructTypes->get(STV); + LLVMContextImpl *pImpl = Context.pImpl; + + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + ST = pImpl->StructTypes.get(STV); if (!ST) { // Value not found. Derive a new type! ST = (StructType*) operator new(sizeof(StructType) + sizeof(PATypeHandle) * ETypes.size()); - new (ST) StructType(ETypes, isPacked); - StructTypes->add(STV, ST); + new (ST) StructType(Context, ETypes, isPacked); + pImpl->StructTypes.add(STV, ST); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *ST << "\n"; + DEBUG(errs() << "Derived new type: " << *ST << "\n"); #endif return ST; } -StructType *StructType::get(const Type *type, ...) { +StructType *StructType::get(LLVMContext &Context, const Type *type, ...) { va_list ap; std::vector<const llvm::Type*> StructFields; va_start(ap, type); @@ -1274,19 +914,12 @@ StructType *StructType::get(const Type *type, ...) { StructFields.push_back(type); type = va_arg(ap, llvm::Type*); } - return llvm::StructType::get(StructFields); + return llvm::StructType::get(Context, StructFields); } bool StructType::isValidElementType(const Type *ElemTy) { - if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy || - ElemTy == Type::MetadataTy) - return false; - - if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy)) - if (PTy->getElementType() == Type::MetadataTy) - return false; - - return true; + return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID && + ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy); } @@ -1294,67 +927,38 @@ bool StructType::isValidElementType(const Type *ElemTy) { // Pointer Type Factory... // -// PointerValType - Define a class to hold the key that goes into the TypeMap -// -namespace llvm { -class PointerValType { - const Type *ValTy; - unsigned AddressSpace; -public: - PointerValType(const Type *val, unsigned as) : ValTy(val), AddressSpace(as) {} - - static PointerValType get(const PointerType *PT) { - return PointerValType(PT->getElementType(), PT->getAddressSpace()); - } - - static unsigned hashTypeStructure(const PointerType *PT) { - return getSubElementHash(PT); - } - - bool operator<(const PointerValType &MTV) const { - if (AddressSpace < MTV.AddressSpace) return true; - return AddressSpace == MTV.AddressSpace && ValTy < MTV.ValTy; - } -}; -} - -static ManagedStatic<TypeMap<PointerValType, PointerType> > PointerTypes; - PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) { assert(ValueType && "Can't get a pointer to <null> type!"); - assert(ValueType != Type::VoidTy && + assert(ValueType->getTypeID() != VoidTyID && "Pointer to void is not valid, use i8* instead!"); assert(isValidElementType(ValueType) && "Invalid type for pointer element!"); PointerValType PVT(ValueType, AddressSpace); PointerType *PT = 0; - sys::SmartScopedLock<true> L(&*TypeMapLock); - PT = PointerTypes->get(PVT); + LLVMContextImpl *pImpl = ValueType->getContext().pImpl; + + sys::SmartScopedLock<true> L(pImpl->TypeMapLock); + PT = pImpl->PointerTypes.get(PVT); if (!PT) { // Value not found. Derive a new type! - PointerTypes->add(PVT, PT = new PointerType(ValueType, AddressSpace)); + pImpl->PointerTypes.add(PVT, PT = new PointerType(ValueType, AddressSpace)); } #ifdef DEBUG_MERGE_TYPES - DOUT << "Derived new type: " << *PT << "\n"; + DEBUG(errs() << "Derived new type: " << *PT << "\n"); #endif return PT; } -PointerType *Type::getPointerTo(unsigned addrs) const { +const PointerType *Type::getPointerTo(unsigned addrs) const { return PointerType::get(this, addrs); } bool PointerType::isValidElementType(const Type *ElemTy) { - if (ElemTy == Type::VoidTy || ElemTy == Type::LabelTy) - return false; - - if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy)) - if (PTy->getElementType() == Type::MetadataTy) - return false; - - return true; + return ElemTy->getTypeID() != VoidTyID && + ElemTy->getTypeID() != LabelTyID && + ElemTy->getTypeID() != MetadataTyID; } @@ -1366,9 +970,10 @@ bool PointerType::isValidElementType(const Type *ElemTy) { // it. This function is called primarily by the PATypeHandle class. void Type::addAbstractTypeUser(AbstractTypeUser *U) const { assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); - AbstractTypeUsersLock->acquire(); + LLVMContextImpl *pImpl = getContext().pImpl; + pImpl->AbstractTypeUsersLock.acquire(); AbstractTypeUsers.push_back(U); - AbstractTypeUsersLock->release(); + pImpl->AbstractTypeUsersLock.release(); } @@ -1378,7 +983,8 @@ void Type::addAbstractTypeUser(AbstractTypeUser *U) const { // is annihilated, because there is no way to get a reference to it ever again. // void Type::removeAbstractTypeUser(AbstractTypeUser *U) const { - AbstractTypeUsersLock->acquire(); + LLVMContextImpl *pImpl = getContext().pImpl; + pImpl->AbstractTypeUsersLock.acquire(); // Search from back to front because we will notify users from back to // front. Also, it is likely that there will be a stack like behavior to @@ -1394,20 +1000,20 @@ void Type::removeAbstractTypeUser(AbstractTypeUser *U) const { AbstractTypeUsers.erase(AbstractTypeUsers.begin()+i); #ifdef DEBUG_MERGE_TYPES - DOUT << " remAbstractTypeUser[" << (void*)this << ", " - << *this << "][" << i << "] User = " << U << "\n"; + DEBUG(errs() << " remAbstractTypeUser[" << (void*)this << ", " + << *this << "][" << i << "] User = " << U << "\n"); #endif if (AbstractTypeUsers.empty() && getRefCount() == 0 && isAbstract()) { #ifdef DEBUG_MERGE_TYPES - DOUT << "DELETEing unused abstract type: <" << *this - << ">[" << (void*)this << "]" << "\n"; + DEBUG(errs() << "DELETEing unused abstract type: <" << *this + << ">[" << (void*)this << "]" << "\n"); #endif this->destroy(); } - AbstractTypeUsersLock->release(); + pImpl->AbstractTypeUsersLock.release(); } // unlockedRefineAbstractTypeTo - This function is used when it is discovered @@ -1421,21 +1027,22 @@ void DerivedType::unlockedRefineAbstractTypeTo(const Type *NewType) { assert(this != NewType && "Can't refine to myself!"); assert(ForwardType == 0 && "This type has already been refined!"); + LLVMContextImpl *pImpl = getContext().pImpl; + // The descriptions may be out of date. Conservatively clear them all! - if (AbstractTypeDescriptions.isConstructed()) - AbstractTypeDescriptions->clear(); + pImpl->AbstractTypeDescriptions.clear(); #ifdef DEBUG_MERGE_TYPES - DOUT << "REFINING abstract type [" << (void*)this << " " - << *this << "] to [" << (void*)NewType << " " - << *NewType << "]!\n"; + DEBUG(errs() << "REFINING abstract type [" << (void*)this << " " + << *this << "] to [" << (void*)NewType << " " + << *NewType << "]!\n"); #endif // Make sure to put the type to be refined to into a holder so that if IT gets // refined, that we will not continue using a dead reference... // PATypeHolder NewTy(NewType); - // Any PATypeHolders referring to this type will now automatically forward o + // Any PATypeHolders referring to this type will now automatically forward to // the type we are resolved to. ForwardType = NewType; if (NewType->isAbstract()) @@ -1458,23 +1065,23 @@ void DerivedType::unlockedRefineAbstractTypeTo(const Type *NewType) { // will not cause users to drop off of the use list. If we resolve to ourself // we succeed! // - AbstractTypeUsersLock->acquire(); + pImpl->AbstractTypeUsersLock.acquire(); while (!AbstractTypeUsers.empty() && NewTy != this) { AbstractTypeUser *User = AbstractTypeUsers.back(); unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; #ifdef DEBUG_MERGE_TYPES - DOUT << " REFINING user " << OldSize-1 << "[" << (void*)User - << "] of abstract type [" << (void*)this << " " - << *this << "] to [" << (void*)NewTy.get() << " " - << *NewTy << "]!\n"; + DEBUG(errs() << " REFINING user " << OldSize-1 << "[" << (void*)User + << "] of abstract type [" << (void*)this << " " + << *this << "] to [" << (void*)NewTy.get() << " " + << *NewTy << "]!\n"); #endif User->refineAbstractType(this, NewTy); assert(AbstractTypeUsers.size() != OldSize && "AbsTyUser did not remove self from user list!"); } - AbstractTypeUsersLock->release(); + pImpl->AbstractTypeUsersLock.release(); // If we were successful removing all users from the type, 'this' will be // deleted when the last PATypeHolder is destroyed or updated from this type. @@ -1488,7 +1095,7 @@ void DerivedType::unlockedRefineAbstractTypeTo(const Type *NewType) { void DerivedType::refineAbstractTypeTo(const Type *NewType) { // All recursive calls will go through unlockedRefineAbstractTypeTo, // to avoid deadlock problems. - sys::SmartScopedLock<true> L(&*TypeMapLock); + sys::SmartScopedLock<true> L(NewType->getContext().pImpl->TypeMapLock); unlockedRefineAbstractTypeTo(NewType); } @@ -1497,10 +1104,12 @@ void DerivedType::refineAbstractTypeTo(const Type *NewType) { // void DerivedType::notifyUsesThatTypeBecameConcrete() { #ifdef DEBUG_MERGE_TYPES - DOUT << "typeIsREFINED type: " << (void*)this << " " << *this << "\n"; + DEBUG(errs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n"); #endif - AbstractTypeUsersLock->acquire(); + LLVMContextImpl *pImpl = getContext().pImpl; + + pImpl->AbstractTypeUsersLock.acquire(); unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize; while (!AbstractTypeUsers.empty()) { AbstractTypeUser *ATU = AbstractTypeUsers.back(); @@ -1509,7 +1118,7 @@ void DerivedType::notifyUsesThatTypeBecameConcrete() { assert(AbstractTypeUsers.size() < OldSize-- && "AbstractTypeUser did not remove itself from the use list!"); } - AbstractTypeUsersLock->release(); + pImpl->AbstractTypeUsersLock.release(); } // refineAbstractType - Called when a contained type is found to be more @@ -1518,11 +1127,13 @@ void DerivedType::notifyUsesThatTypeBecameConcrete() { // void FunctionType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - FunctionTypes->RefineAbstractType(this, OldType, NewType); + LLVMContextImpl *pImpl = OldType->getContext().pImpl; + pImpl->FunctionTypes.RefineAbstractType(this, OldType, NewType); } void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) { - FunctionTypes->TypeBecameConcrete(this, AbsTy); + LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; + pImpl->FunctionTypes.TypeBecameConcrete(this, AbsTy); } @@ -1532,11 +1143,13 @@ void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) { // void ArrayType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - ArrayTypes->RefineAbstractType(this, OldType, NewType); + LLVMContextImpl *pImpl = OldType->getContext().pImpl; + pImpl->ArrayTypes.RefineAbstractType(this, OldType, NewType); } void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { - ArrayTypes->TypeBecameConcrete(this, AbsTy); + LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; + pImpl->ArrayTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more @@ -1545,11 +1158,13 @@ void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { // void VectorType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - VectorTypes->RefineAbstractType(this, OldType, NewType); + LLVMContextImpl *pImpl = OldType->getContext().pImpl; + pImpl->VectorTypes.RefineAbstractType(this, OldType, NewType); } void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { - VectorTypes->TypeBecameConcrete(this, AbsTy); + LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; + pImpl->VectorTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more @@ -1558,11 +1173,13 @@ void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { // void StructType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - StructTypes->RefineAbstractType(this, OldType, NewType); + LLVMContextImpl *pImpl = OldType->getContext().pImpl; + pImpl->StructTypes.RefineAbstractType(this, OldType, NewType); } void StructType::typeBecameConcrete(const DerivedType *AbsTy) { - StructTypes->TypeBecameConcrete(this, AbsTy); + LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; + pImpl->StructTypes.TypeBecameConcrete(this, AbsTy); } // refineAbstractType - Called when a contained type is found to be more @@ -1571,11 +1188,13 @@ void StructType::typeBecameConcrete(const DerivedType *AbsTy) { // void PointerType::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - PointerTypes->RefineAbstractType(this, OldType, NewType); + LLVMContextImpl *pImpl = OldType->getContext().pImpl; + pImpl->PointerTypes.RefineAbstractType(this, OldType, NewType); } void PointerType::typeBecameConcrete(const DerivedType *AbsTy) { - PointerTypes->TypeBecameConcrete(this, AbsTy); + LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; + pImpl->PointerTypes.TypeBecameConcrete(this, AbsTy); } bool SequentialType::indexValid(const Value *V) const { @@ -1585,19 +1204,6 @@ bool SequentialType::indexValid(const Value *V) const { } namespace llvm { -std::ostream &operator<<(std::ostream &OS, const Type *T) { - if (T == 0) - OS << "<null> value!\n"; - else - T->print(OS); - return OS; -} - -std::ostream &operator<<(std::ostream &OS, const Type &T) { - T.print(OS); - return OS; -} - raw_ostream &operator<<(raw_ostream &OS, const Type &T) { T.print(OS); return OS; diff --git a/lib/VMCore/TypeSymbolTable.cpp b/lib/VMCore/TypeSymbolTable.cpp index 5ae60e28d7f0..f31ea6693e0b 100644 --- a/lib/VMCore/TypeSymbolTable.cpp +++ b/lib/VMCore/TypeSymbolTable.cpp @@ -14,8 +14,9 @@ #include "llvm/TypeSymbolTable.h" #include "llvm/DerivedTypes.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/RWMutex.h" #include "llvm/System/Threading.h" #include <algorithm> @@ -34,22 +35,22 @@ TypeSymbolTable::~TypeSymbolTable() { } } -std::string TypeSymbolTable::getUniqueName(const std::string &BaseName) const { +std::string TypeSymbolTable::getUniqueName(const StringRef &BaseName) const { std::string TryName = BaseName; - sys::SmartScopedReader<true> Reader(&*TypeSymbolTableLock); + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); const_iterator End = tmap.end(); // See if the name exists while (tmap.find(TryName) != End) // Loop until we find a free - TryName = BaseName + utostr(++LastUnique); // name in the symbol table + TryName = BaseName.str() + utostr(++LastUnique); // name in the symbol table return TryName; } // lookup a type by name - returns null on failure -Type* TypeSymbolTable::lookup(const std::string& Name) const { - sys::SmartScopedReader<true> Reader(&*TypeSymbolTableLock); +Type* TypeSymbolTable::lookup(const StringRef &Name) const { + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); const_iterator TI = tmap.find(Name); Type* result = 0; @@ -58,6 +59,17 @@ Type* TypeSymbolTable::lookup(const std::string& Name) const { return result; } +TypeSymbolTable::iterator TypeSymbolTable::find(const StringRef &Name) { + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); + return tmap.find(Name); +} + +TypeSymbolTable::const_iterator +TypeSymbolTable::find(const StringRef &Name) const { + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); + return tmap.find(Name); +} + // remove - Remove a type from the symbol table... Type* TypeSymbolTable::remove(iterator Entry) { TypeSymbolTableLock->writer_acquire(); @@ -67,7 +79,7 @@ Type* TypeSymbolTable::remove(iterator Entry) { #if DEBUG_SYMBOL_TABLE dump(); - cerr << " Removing Value: " << Result->getName() << "\n"; + errs() << " Removing Value: " << Result->getDescription() << "\n"; #endif tmap.erase(Entry); @@ -78,9 +90,9 @@ Type* TypeSymbolTable::remove(iterator Entry) { // list... if (Result->isAbstract()) { #if DEBUG_ABSTYPE - cerr << "Removing abstract type from symtab" - << Result->getDescription() - << "\n"; + errs() << "Removing abstract type from symtab" + << Result->getDescription() + << "\n"; #endif cast<DerivedType>(Result)->removeAbstractTypeUser(this); } @@ -90,17 +102,17 @@ Type* TypeSymbolTable::remove(iterator Entry) { // insert - Insert a type into the symbol table with the specified name... -void TypeSymbolTable::insert(const std::string& Name, const Type* T) { +void TypeSymbolTable::insert(const StringRef &Name, const Type* T) { assert(T && "Can't insert null type into symbol table!"); TypeSymbolTableLock->writer_acquire(); - if (tmap.insert(make_pair(Name, T)).second) { + if (tmap.insert(std::make_pair(Name, T)).second) { // Type inserted fine with no conflict. #if DEBUG_SYMBOL_TABLE dump(); - cerr << " Inserted type: " << Name << ": " << T->getDescription() << "\n"; + errs() << " Inserted type: " << Name << ": " << T->getDescription() << "\n"; #endif } else { // If there is a name conflict... @@ -112,8 +124,8 @@ void TypeSymbolTable::insert(const std::string& Name, const Type* T) { #if DEBUG_SYMBOL_TABLE dump(); - cerr << " Inserting type: " << UniqueName << ": " - << T->getDescription() << "\n"; + errs() << " Inserting type: " << UniqueName << ": " + << T->getDescription() << "\n"; #endif // Insert the tmap entry @@ -126,7 +138,7 @@ void TypeSymbolTable::insert(const std::string& Name, const Type* T) { if (T->isAbstract()) { cast<DerivedType>(T)->addAbstractTypeUser(this); #if DEBUG_ABSTYPE - cerr << "Added abstract type to ST: " << T->getDescription() << "\n"; + errs() << "Added abstract type to ST: " << T->getDescription() << "\n"; #endif } } @@ -134,7 +146,7 @@ void TypeSymbolTable::insert(const std::string& Name, const Type* T) { // This function is called when one of the types in the type plane are refined void TypeSymbolTable::refineAbstractType(const DerivedType *OldType, const Type *NewType) { - sys::SmartScopedReader<true> Reader(&*TypeSymbolTableLock); + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); // Loop over all of the types in the symbol table, replacing any references // to OldType with references to NewType. Note that there may be multiple @@ -144,14 +156,14 @@ void TypeSymbolTable::refineAbstractType(const DerivedType *OldType, for (iterator I = begin(), E = end(); I != E; ++I) { if (I->second == (Type*)OldType) { // FIXME when Types aren't const. #if DEBUG_ABSTYPE - cerr << "Removing type " << OldType->getDescription() << "\n"; + errs() << "Removing type " << OldType->getDescription() << "\n"; #endif OldType->removeAbstractTypeUser(this); I->second = (Type*)NewType; // TODO FIXME when types aren't const if (NewType->isAbstract()) { #if DEBUG_ABSTYPE - cerr << "Added type " << NewType->getDescription() << "\n"; + errs() << "Added type " << NewType->getDescription() << "\n"; #endif cast<DerivedType>(NewType)->addAbstractTypeUser(this); } @@ -165,21 +177,21 @@ void TypeSymbolTable::typeBecameConcrete(const DerivedType *AbsTy) { // Loop over all of the types in the symbol table, dropping any abstract // type user entries for AbsTy which occur because there are names for the // type. - sys::SmartScopedReader<true> Reader(&*TypeSymbolTableLock); + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); for (iterator TI = begin(), TE = end(); TI != TE; ++TI) if (TI->second == const_cast<Type*>(static_cast<const Type*>(AbsTy))) AbsTy->removeAbstractTypeUser(this); } static void DumpTypes(const std::pair<const std::string, const Type*>& T ) { - cerr << " '" << T.first << "' = "; + errs() << " '" << T.first << "' = "; T.second->dump(); - cerr << "\n"; + errs() << "\n"; } void TypeSymbolTable::dump() const { - cerr << "TypeSymbolPlane: "; - sys::SmartScopedReader<true> Reader(&*TypeSymbolTableLock); + errs() << "TypeSymbolPlane: "; + sys::SmartScopedReader<true> Reader(*TypeSymbolTableLock); for_each(tmap.begin(), tmap.end(), DumpTypes); } diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h new file mode 100644 index 000000000000..e7950bd211ff --- /dev/null +++ b/lib/VMCore/TypesContext.h @@ -0,0 +1,424 @@ +//===-- TypesContext.h - Types-related Context Internals ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines various helper methods and classes used by +// LLVMContextImpl for creating and managing types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TYPESCONTEXT_H +#define LLVM_TYPESCONTEXT_H + +#include "llvm/ADT/STLExtras.h" +#include <map> + + +//===----------------------------------------------------------------------===// +// Derived Type Factory Functions +//===----------------------------------------------------------------------===// +namespace llvm { + +/// getSubElementHash - Generate a hash value for all of the SubType's of this +/// type. The hash value is guaranteed to be zero if any of the subtypes are +/// an opaque type. Otherwise we try to mix them in as well as possible, but do +/// not look at the subtype's subtype's. +static unsigned getSubElementHash(const Type *Ty) { + unsigned HashVal = 0; + for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); + I != E; ++I) { + HashVal *= 32; + const Type *SubTy = I->get(); + HashVal += SubTy->getTypeID(); + switch (SubTy->getTypeID()) { + default: break; + case Type::OpaqueTyID: return 0; // Opaque -> hash = 0 no matter what. + case Type::IntegerTyID: + HashVal ^= (cast<IntegerType>(SubTy)->getBitWidth() << 3); + break; + case Type::FunctionTyID: + HashVal ^= cast<FunctionType>(SubTy)->getNumParams()*2 + + cast<FunctionType>(SubTy)->isVarArg(); + break; + case Type::ArrayTyID: + HashVal ^= cast<ArrayType>(SubTy)->getNumElements(); + break; + case Type::VectorTyID: + HashVal ^= cast<VectorType>(SubTy)->getNumElements(); + break; + case Type::StructTyID: + HashVal ^= cast<StructType>(SubTy)->getNumElements(); + break; + case Type::PointerTyID: + HashVal ^= cast<PointerType>(SubTy)->getAddressSpace(); + break; + } + } + return HashVal ? HashVal : 1; // Do not return zero unless opaque subty. +} + +//===----------------------------------------------------------------------===// +// Integer Type Factory... +// +class IntegerValType { + uint32_t bits; +public: + IntegerValType(uint16_t numbits) : bits(numbits) {} + + static IntegerValType get(const IntegerType *Ty) { + return IntegerValType(Ty->getBitWidth()); + } + + static unsigned hashTypeStructure(const IntegerType *Ty) { + return (unsigned)Ty->getBitWidth(); + } + + inline bool operator<(const IntegerValType &IVT) const { + return bits < IVT.bits; + } +}; + +// PointerValType - Define a class to hold the key that goes into the TypeMap +// +class PointerValType { + const Type *ValTy; + unsigned AddressSpace; +public: + PointerValType(const Type *val, unsigned as) : ValTy(val), AddressSpace(as) {} + + static PointerValType get(const PointerType *PT) { + return PointerValType(PT->getElementType(), PT->getAddressSpace()); + } + + static unsigned hashTypeStructure(const PointerType *PT) { + return getSubElementHash(PT); + } + + bool operator<(const PointerValType &MTV) const { + if (AddressSpace < MTV.AddressSpace) return true; + return AddressSpace == MTV.AddressSpace && ValTy < MTV.ValTy; + } +}; + +//===----------------------------------------------------------------------===// +// Array Type Factory... +// +class ArrayValType { + const Type *ValTy; + uint64_t Size; +public: + ArrayValType(const Type *val, uint64_t sz) : ValTy(val), Size(sz) {} + + static ArrayValType get(const ArrayType *AT) { + return ArrayValType(AT->getElementType(), AT->getNumElements()); + } + + static unsigned hashTypeStructure(const ArrayType *AT) { + return (unsigned)AT->getNumElements(); + } + + inline bool operator<(const ArrayValType &MTV) const { + if (Size < MTV.Size) return true; + return Size == MTV.Size && ValTy < MTV.ValTy; + } +}; + +//===----------------------------------------------------------------------===// +// Vector Type Factory... +// +class VectorValType { + const Type *ValTy; + unsigned Size; +public: + VectorValType(const Type *val, int sz) : ValTy(val), Size(sz) {} + + static VectorValType get(const VectorType *PT) { + return VectorValType(PT->getElementType(), PT->getNumElements()); + } + + static unsigned hashTypeStructure(const VectorType *PT) { + return PT->getNumElements(); + } + + inline bool operator<(const VectorValType &MTV) const { + if (Size < MTV.Size) return true; + return Size == MTV.Size && ValTy < MTV.ValTy; + } +}; + +// StructValType - Define a class to hold the key that goes into the TypeMap +// +class StructValType { + std::vector<const Type*> ElTypes; + bool packed; +public: + StructValType(const std::vector<const Type*> &args, bool isPacked) + : ElTypes(args), packed(isPacked) {} + + static StructValType get(const StructType *ST) { + std::vector<const Type *> ElTypes; + ElTypes.reserve(ST->getNumElements()); + for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) + ElTypes.push_back(ST->getElementType(i)); + + return StructValType(ElTypes, ST->isPacked()); + } + + static unsigned hashTypeStructure(const StructType *ST) { + return ST->getNumElements(); + } + + inline bool operator<(const StructValType &STV) const { + if (ElTypes < STV.ElTypes) return true; + else if (ElTypes > STV.ElTypes) return false; + else return (int)packed < (int)STV.packed; + } +}; + +// FunctionValType - Define a class to hold the key that goes into the TypeMap +// +class FunctionValType { + const Type *RetTy; + std::vector<const Type*> ArgTypes; + bool isVarArg; +public: + FunctionValType(const Type *ret, const std::vector<const Type*> &args, + bool isVA) : RetTy(ret), ArgTypes(args), isVarArg(isVA) {} + + static FunctionValType get(const FunctionType *FT); + + static unsigned hashTypeStructure(const FunctionType *FT) { + unsigned Result = FT->getNumParams()*2 + FT->isVarArg(); + return Result; + } + + inline bool operator<(const FunctionValType &MTV) const { + if (RetTy < MTV.RetTy) return true; + if (RetTy > MTV.RetTy) return false; + if (isVarArg < MTV.isVarArg) return true; + if (isVarArg > MTV.isVarArg) return false; + if (ArgTypes < MTV.ArgTypes) return true; + if (ArgTypes > MTV.ArgTypes) return false; + return false; + } +}; + +class TypeMapBase { +protected: + /// TypesByHash - Keep track of types by their structure hash value. Note + /// that we only keep track of types that have cycles through themselves in + /// this map. + /// + std::multimap<unsigned, PATypeHolder> TypesByHash; + +public: + ~TypeMapBase() { + // PATypeHolder won't destroy non-abstract types. + // We can't destroy them by simply iterating, because + // they may contain references to each-other. + for (std::multimap<unsigned, PATypeHolder>::iterator I + = TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) { + Type *Ty = const_cast<Type*>(I->second.Ty); + I->second.destroy(); + // We can't invoke destroy or delete, because the type may + // contain references to already freed types. + // So we have to destruct the object the ugly way. + if (Ty) { + Ty->AbstractTypeUsers.clear(); + static_cast<const Type*>(Ty)->Type::~Type(); + operator delete(Ty); + } + } + } + + void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { + std::multimap<unsigned, PATypeHolder>::iterator I = + TypesByHash.lower_bound(Hash); + for (; I != TypesByHash.end() && I->first == Hash; ++I) { + if (I->second == Ty) { + TypesByHash.erase(I); + return; + } + } + + // This must be do to an opaque type that was resolved. Switch down to hash + // code of zero. + assert(Hash && "Didn't find type entry!"); + RemoveFromTypesByHash(0, Ty); + } + + /// TypeBecameConcrete - When Ty gets a notification that TheType just became + /// concrete, drop uses and make Ty non-abstract if we should. + void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) { + // If the element just became concrete, remove 'ty' from the abstract + // type user list for the type. Do this for as many times as Ty uses + // OldType. + for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); + I != E; ++I) + if (I->get() == TheType) + TheType->removeAbstractTypeUser(Ty); + + // If the type is currently thought to be abstract, rescan all of our + // subtypes to see if the type has just become concrete! Note that this + // may send out notifications to AbstractTypeUsers that types become + // concrete. + if (Ty->isAbstract()) + Ty->PromoteAbstractToConcrete(); + } +}; + +// TypeMap - Make sure that only one instance of a particular type may be +// created on any given run of the compiler... note that this involves updating +// our map if an abstract type gets refined somehow. +// +template<class ValType, class TypeClass> +class TypeMap : public TypeMapBase { + std::map<ValType, PATypeHolder> Map; +public: + typedef typename std::map<ValType, PATypeHolder>::iterator iterator; + ~TypeMap() { print("ON EXIT"); } + + inline TypeClass *get(const ValType &V) { + iterator I = Map.find(V); + return I != Map.end() ? cast<TypeClass>((Type*)I->second.get()) : 0; + } + + inline void add(const ValType &V, TypeClass *Ty) { + Map.insert(std::make_pair(V, Ty)); + + // If this type has a cycle, remember it. + TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty)); + print("add"); + } + + /// RefineAbstractType - This method is called after we have merged a type + /// with another one. We must now either merge the type away with + /// some other type or reinstall it in the map with it's new configuration. + void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType, + const Type *NewType) { +#ifdef DEBUG_MERGE_TYPES + DEBUG(errs() << "RefineAbstractType(" << (void*)OldType << "[" << *OldType + << "], " << (void*)NewType << " [" << *NewType << "])\n"); +#endif + + // Otherwise, we are changing one subelement type into another. Clearly the + // OldType must have been abstract, making us abstract. + assert(Ty->isAbstract() && "Refining a non-abstract type!"); + assert(OldType != NewType); + + // Make a temporary type holder for the type so that it doesn't disappear on + // us when we erase the entry from the map. + PATypeHolder TyHolder = Ty; + + // The old record is now out-of-date, because one of the children has been + // updated. Remove the obsolete entry from the map. + unsigned NumErased = Map.erase(ValType::get(Ty)); + assert(NumErased && "Element not found!"); NumErased = NumErased; + + // Remember the structural hash for the type before we start hacking on it, + // in case we need it later. + unsigned OldTypeHash = ValType::hashTypeStructure(Ty); + + // Find the type element we are refining... and change it now! + for (unsigned i = 0, e = Ty->getNumContainedTypes(); i != e; ++i) + if (Ty->ContainedTys[i] == OldType) + Ty->ContainedTys[i] = NewType; + unsigned NewTypeHash = ValType::hashTypeStructure(Ty); + + // If there are no cycles going through this node, we can do a simple, + // efficient lookup in the map, instead of an inefficient nasty linear + // lookup. + if (!TypeHasCycleThroughItself(Ty)) { + typename std::map<ValType, PATypeHolder>::iterator I; + bool Inserted; + + tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty)); + if (!Inserted) { + // Refined to a different type altogether? + RemoveFromTypesByHash(OldTypeHash, Ty); + + // We already have this type in the table. Get rid of the newly refined + // type. + TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); + Ty->unlockedRefineAbstractTypeTo(NewTy); + return; + } + } else { + // Now we check to see if there is an existing entry in the table which is + // structurally identical to the newly refined type. If so, this type + // gets refined to the pre-existing type. + // + std::multimap<unsigned, PATypeHolder>::iterator I, E, Entry; + tie(I, E) = TypesByHash.equal_range(NewTypeHash); + Entry = E; + for (; I != E; ++I) { + if (I->second == Ty) { + // Remember the position of the old type if we see it in our scan. + Entry = I; + } else { + if (TypesEqual(Ty, I->second)) { + TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get()); + + // Remove the old entry form TypesByHash. If the hash values differ + // now, remove it from the old place. Otherwise, continue scanning + // withing this hashcode to reduce work. + if (NewTypeHash != OldTypeHash) { + RemoveFromTypesByHash(OldTypeHash, Ty); + } else { + if (Entry == E) { + // Find the location of Ty in the TypesByHash structure if we + // haven't seen it already. + while (I->second != Ty) { + ++I; + assert(I != E && "Structure doesn't contain type??"); + } + Entry = I; + } + TypesByHash.erase(Entry); + } + Ty->unlockedRefineAbstractTypeTo(NewTy); + return; + } + } + } + + // If there is no existing type of the same structure, we reinsert an + // updated record into the map. + Map.insert(std::make_pair(ValType::get(Ty), Ty)); + } + + // If the hash codes differ, update TypesByHash + if (NewTypeHash != OldTypeHash) { + RemoveFromTypesByHash(OldTypeHash, Ty); + TypesByHash.insert(std::make_pair(NewTypeHash, Ty)); + } + + // If the type is currently thought to be abstract, rescan all of our + // subtypes to see if the type has just become concrete! Note that this + // may send out notifications to AbstractTypeUsers that types become + // concrete. + if (Ty->isAbstract()) + Ty->PromoteAbstractToConcrete(); + } + + void print(const char *Arg) const { +#ifdef DEBUG_MERGE_TYPES + DEBUG(errs() << "TypeMap<>::" << Arg << " table contents:\n"); + unsigned i = 0; + for (typename std::map<ValType, PATypeHolder>::const_iterator I + = Map.begin(), E = Map.end(); I != E; ++I) + DEBUG(errs() << " " << (++i) << ". " << (void*)I->second.get() << " " + << *I->second.get() << "\n"); +#endif + } + + void dump() const { print("dump output"); } +}; +} + +#endif diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp index b25415a3d14e..b7fd92f9b066 100644 --- a/lib/VMCore/Use.cpp +++ b/lib/VMCore/Use.cpp @@ -128,7 +128,7 @@ void Use::zap(Use *Start, const Use *Stop, bool del) { // AugmentedUse layout struct //===----------------------------------------------------------------------===// -struct AugmentedUse : Use { +struct AugmentedUse : public Use { PointerIntPair<User*, 1, Tag> ref; AugmentedUse(); // not implemented }; diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index c952b7888cdd..ba72af635cdc 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -11,17 +11,23 @@ // //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h" #include "llvm/Constant.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/InstrTypes.h" #include "llvm/Instructions.h" +#include "llvm/Operator.h" #include "llvm/Module.h" +#include "llvm/Metadata.h" #include "llvm/ValueSymbolTable.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/RWMutex.h" #include "llvm/System/Threading.h" #include "llvm/ADT/DenseMap.h" @@ -38,23 +44,31 @@ static inline const Type *checkType(const Type *Ty) { } Value::Value(const Type *ty, unsigned scid) - : SubclassID(scid), HasValueHandle(0), SubclassData(0), VTy(checkType(ty)), + : SubclassID(scid), HasValueHandle(0), HasMetadata(0), + SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)), UseList(0), Name(0) { if (isa<CallInst>(this) || isa<InvokeInst>(this)) - assert((VTy->isFirstClassType() || VTy == Type::VoidTy || + assert((VTy->isFirstClassType() || + VTy == Type::getVoidTy(ty->getContext()) || isa<OpaqueType>(ty) || VTy->getTypeID() == Type::StructTyID) && "invalid CallInst type!"); else if (!isa<Constant>(this) && !isa<BasicBlock>(this)) - assert((VTy->isFirstClassType() || VTy == Type::VoidTy || + assert((VTy->isFirstClassType() || + VTy == Type::getVoidTy(ty->getContext()) || isa<OpaqueType>(ty)) && "Cannot create non-first-class values except for constants!"); } Value::~Value() { + if (HasMetadata) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsDeleted(this); + } + // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsDeleted(this); - + #ifndef NDEBUG // Only in -g mode... // Check to make sure that there are no uses of this value that are still // around when the value is destroyed. If there are, then we have a dangling @@ -63,9 +77,9 @@ Value::~Value() { // a <badref> // if (!use_empty()) { - cerr << "While deleting: " << *VTy << " %" << getNameStr() << "\n"; + errs() << "While deleting: " << *VTy << " %" << getNameStr() << "\n"; for (use_iterator I = use_begin(), E = use_end(); I != E; ++I) - cerr << "Use still stuck around after Def is destroyed:" + errs() << "Use still stuck around after Def is destroyed:" << **I << "\n"; } #endif @@ -75,7 +89,7 @@ Value::~Value() { // at this point. if (Name) Name->Destroy(); - + // There should be no uses of this object anymore, remove it. LeakDetector::removeGarbageObject(this); } @@ -128,61 +142,57 @@ static bool getSymTab(Value *V, ValueSymbolTable *&ST) { if (Function *PP = P->getParent()) ST = &PP->getValueSymbolTable(); } else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) { - if (Function *P = BB->getParent()) + if (Function *P = BB->getParent()) ST = &P->getValueSymbolTable(); } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) { - if (Module *P = GV->getParent()) + if (Module *P = GV->getParent()) ST = &P->getValueSymbolTable(); } else if (Argument *A = dyn_cast<Argument>(V)) { - if (Function *P = A->getParent()) + if (Function *P = A->getParent()) + ST = &P->getValueSymbolTable(); + } else if (NamedMDNode *N = dyn_cast<NamedMDNode>(V)) { + if (Module *P = N->getParent()) { ST = &P->getValueSymbolTable(); - } else { + } + } else if (isa<MDString>(V)) + return true; + else { assert(isa<Constant>(V) && "Unknown value type!"); return true; // no name is setable for this. } return false; } -/// getNameStart - Return a pointer to a null terminated string for this name. -/// Note that names can have null characters within the string as well as at -/// their end. This always returns a non-null pointer. -const char *Value::getNameStart() const { - if (Name == 0) return ""; - return Name->getKeyData(); +StringRef Value::getName() const { + // Make sure the empty string is still a C string. For historical reasons, + // some clients want to call .data() on the result and expect it to be null + // terminated. + if (!Name) return StringRef("", 0); + return Name->getKey(); } -/// getNameLen - Return the length of the string, correctly handling nul -/// characters embedded into them. -unsigned Value::getNameLen() const { - return Name ? Name->getKeyLength() : 0; +std::string Value::getNameStr() const { + return getName().str(); } -/// isName - Return true if this value has the name specified by the provided -/// nul terminated string. -bool Value::isName(const char *N) const { - unsigned InLen = strlen(N); - return InLen == getNameLen() && memcmp(getNameStart(), N, InLen) == 0; -} +void Value::setName(const Twine &NewName) { + // Fast path for common IRBuilder case of setName("") when there is no name. + if (NewName.isTriviallyEmpty() && !hasName()) + return; + SmallString<256> NameData; + NewName.toVector(NameData); -std::string Value::getNameStr() const { - if (Name == 0) return ""; - return std::string(Name->getKeyData(), - Name->getKeyData()+Name->getKeyLength()); -} + const char *NameStr = NameData.data(); + unsigned NameLen = NameData.size(); -void Value::setName(const std::string &name) { - setName(&name[0], name.size()); -} + // Name isn't changing? + if (getName() == StringRef(NameStr, NameLen)) + return; -void Value::setName(const char *Name) { - setName(Name, Name ? strlen(Name) : 0); -} + assert(getType() != Type::getVoidTy(getContext()) && + "Cannot assign a name to void values!"); -void Value::setName(const char *NameStr, unsigned NameLen) { - if (NameLen == 0 && !hasName()) return; - assert(getType() != Type::VoidTy && "Cannot assign a name to void values!"); - // Get the symbol table to update for this object. ValueSymbolTable *ST; if (getSymTab(this, ST)) @@ -195,32 +205,22 @@ void Value::setName(const char *NameStr, unsigned NameLen) { Name = 0; return; } - - if (Name) { - // Name isn't changing? - if (NameLen == Name->getKeyLength() && - !memcmp(Name->getKeyData(), NameStr, NameLen)) - return; + + if (Name) Name->Destroy(); - } - + // NOTE: Could optimize for the case the name is shrinking to not deallocate // then reallocated. - + // Create the new name. Name = ValueName::Create(NameStr, NameStr+NameLen); Name->setValue(this); return; } - + // NOTE: Could optimize for the case the name is shrinking to not deallocate // then reallocated. if (hasName()) { - // Name isn't changing? - if (NameLen == Name->getKeyLength() && - !memcmp(Name->getKeyData(), NameStr, NameLen)) - return; - // Remove old name. ST->removeValueName(Name); Name->Destroy(); @@ -231,12 +231,12 @@ void Value::setName(const char *NameStr, unsigned NameLen) { } // Name is changing to something new. - Name = ST->createValueName(NameStr, NameLen, this); + Name = ST->createValueName(StringRef(NameStr, NameLen), this); } /// takeName - transfer the name from V to this value, setting V's name to -/// empty. It is an error to call V->takeName(V). +/// empty. It is an error to call V->takeName(V). void Value::takeName(Value *V) { ValueSymbolTable *ST = 0; // If this value has a name, drop it. @@ -245,36 +245,36 @@ void Value::takeName(Value *V) { if (getSymTab(this, ST)) { // We can't set a name on this value, but we need to clear V's name if // it has one. - if (V->hasName()) V->setName(0, 0); + if (V->hasName()) V->setName(""); return; // Cannot set a name on this value (e.g. constant). } - + // Remove old name. if (ST) ST->removeValueName(Name); Name->Destroy(); Name = 0; - } - + } + // Now we know that this has no name. - + // If V has no name either, we're done. if (!V->hasName()) return; - + // Get this's symtab if we didn't before. if (!ST) { if (getSymTab(this, ST)) { // Clear V's name. - V->setName(0, 0); + V->setName(""); return; // Cannot set a name on this value (e.g. constant). } } - + // Get V's ST, this should always succed, because V has a name. ValueSymbolTable *VST; bool Failure = getSymTab(V, VST); assert(!Failure && "V has a name, so it should have a ST!"); Failure=Failure; - + // If these values are both in the same symtab, we can do this very fast. // This works even if both values have no symtab yet. if (ST == VST) { @@ -284,16 +284,16 @@ void Value::takeName(Value *V) { Name->setValue(this); return; } - + // Otherwise, things are slightly more complex. Remove V's name from VST and // then reinsert it into ST. - + if (VST) VST->removeValueName(V->Name); Name = V->Name; V->Name = 0; Name->setValue(this); - + if (ST) ST->reinsertValue(this); } @@ -309,7 +309,11 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); - + if (HasMetadata) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsRAUWd(this, New); + } + while (!use_empty()) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a @@ -320,7 +324,7 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { continue; } } - + U.set(New); } } @@ -339,23 +343,16 @@ Value *Value::stripPointerCasts() { return this; Value *V = this; do { - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i) - if (!CE->getOperand(i)->isNullValue()) - return V; - V = CE->getOperand(0); - } else if (CE->getOpcode() == Instruction::BitCast) { - V = CE->getOperand(0); - } else { - return V; - } - } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) { + if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { if (!GEP->hasAllZeroIndices()) return V; - V = GEP->getOperand(0); - } else if (BitCastInst *CI = dyn_cast<BitCastInst>(V)) { - V = CI->getOperand(0); + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast<Operator>(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + if (GA->mayBeOverridden()) + return V; + V = GA->getAliasee(); } else { return V; } @@ -369,15 +366,14 @@ Value *Value::getUnderlyingObject() { Value *V = this; unsigned MaxLookup = 6; do { - if (Instruction *I = dyn_cast<Instruction>(V)) { - if (!isa<BitCastInst>(I) && !isa<GetElementPtrInst>(I)) - return V; - V = I->getOperand(0); - } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() != Instruction::BitCast && - CE->getOpcode() != Instruction::GetElementPtr) + if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast<Operator>(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) { + if (GA->mayBeOverridden()) return V; - V = CE->getOperand(0); + V = GA->getAliasee(); } else { return V; } @@ -390,7 +386,7 @@ Value *Value::getUnderlyingObject() { /// return the value in the PHI node corresponding to PredBB. If not, return /// ourself. This is useful if you want to know the value something has in a /// predecessor block. -Value *Value::DoPHITranslation(const BasicBlock *CurBB, +Value *Value::DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) { PHINode *PN = dyn_cast<PHINode>(this); if (PN && PN->getParent() == CurBB) @@ -398,22 +394,17 @@ Value *Value::DoPHITranslation(const BasicBlock *CurBB, return this; } +LLVMContext &Value::getContext() const { return VTy->getContext(); } + //===----------------------------------------------------------------------===// // ValueHandleBase Class //===----------------------------------------------------------------------===// -/// ValueHandles - This map keeps track of all of the value handles that are -/// watching a Value*. The Value::HasValueHandle bit is used to know whether or -/// not a value has an entry in this map. -typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy; -static ManagedStatic<ValueHandlesTy> ValueHandles; -static ManagedStatic<sys::SmartRWMutex<true> > ValueHandlesLock; - /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where /// List is known to point into the existing use list. void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { assert(List && "Handle list is null?"); - + // Splice ourselves into the list. Next = *List; *List = this; @@ -424,43 +415,54 @@ void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { } } +void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) { + assert(List && "Must insert after existing node"); + + Next = List->Next; + setPrevPtr(&List->Next); + List->Next = this; + if (Next) + Next->setPrevPtr(&Next); +} + /// AddToUseList - Add this ValueHandle to the use list for VP. void ValueHandleBase::AddToUseList() { assert(VP && "Null pointer doesn't have a use list!"); + + LLVMContextImpl *pImpl = VP->getContext().pImpl; + if (VP->HasValueHandle) { // If this value already has a ValueHandle, then it must be in the // ValueHandles map already. - sys::SmartScopedReader<true> Reader(&*ValueHandlesLock); - ValueHandleBase *&Entry = (*ValueHandles)[VP]; + ValueHandleBase *&Entry = pImpl->ValueHandles[VP]; assert(Entry != 0 && "Value doesn't have any handles?"); AddToExistingUseList(&Entry); return; } - + // Ok, it doesn't have any handles yet, so we must insert it into the // DenseMap. However, doing this insertion could cause the DenseMap to // reallocate itself, which would invalidate all of the PrevP pointers that // point into the old table. Handle this by checking for reallocation and // updating the stale pointers only if needed. - sys::SmartScopedWriter<true> Writer(&*ValueHandlesLock); - ValueHandlesTy &Handles = *ValueHandles; + DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles; const void *OldBucketPtr = Handles.getPointerIntoBucketsArray(); - + ValueHandleBase *&Entry = Handles[VP]; assert(Entry == 0 && "Value really did already have handles?"); AddToExistingUseList(&Entry); VP->HasValueHandle = true; - + // If reallocation didn't happen or if this was the first insertion, don't // walk the table. - if (Handles.isPointerIntoBucketsArray(OldBucketPtr) || + if (Handles.isPointerIntoBucketsArray(OldBucketPtr) || Handles.size() == 1) { return; } - + // Okay, reallocation did happen. Fix the Prev Pointers. - for (ValueHandlesTy::iterator I = Handles.begin(), E = Handles.end(); - I != E; ++I) { + for (DenseMap<Value*, ValueHandleBase*>::iterator I = Handles.begin(), + E = Handles.end(); I != E; ++I) { assert(I->second && I->first == I->second->VP && "List invariant broken!"); I->second->setPrevPtr(&I->second); } @@ -473,19 +475,19 @@ void ValueHandleBase::RemoveFromUseList() { // Unlink this from its use list. ValueHandleBase **PrevPtr = getPrevPtr(); assert(*PrevPtr == this && "List invariant broken"); - + *PrevPtr = Next; if (Next) { assert(Next->getPrevPtr() == &Next && "List invariant broken"); Next->setPrevPtr(PrevPtr); return; } - + // If the Next pointer was null, then it is possible that this was the last // ValueHandle watching VP. If so, delete its entry from the ValueHandles // map. - sys::SmartScopedWriter<true> Writer(&*ValueHandlesLock); - ValueHandlesTy &Handles = *ValueHandles; + LLVMContextImpl *pImpl = VP->getContext().pImpl; + DenseMap<Value*, ValueHandleBase*> &Handles = pImpl->ValueHandles; if (Handles.isPointerIntoBucketsArray(PrevPtr)) { Handles.erase(VP); VP->HasValueHandle = false; @@ -498,67 +500,91 @@ void ValueHandleBase::ValueIsDeleted(Value *V) { // Get the linked list base, which is guaranteed to exist since the // HasValueHandle flag is set. - ValueHandlesLock->reader_acquire(); - ValueHandleBase *Entry = (*ValueHandles)[V]; - ValueHandlesLock->reader_release(); + LLVMContextImpl *pImpl = V->getContext().pImpl; + ValueHandleBase *Entry = pImpl->ValueHandles[V]; assert(Entry && "Value bit set but no entries exist"); - - while (Entry) { - // Advance pointer to avoid invalidation. - ValueHandleBase *ThisNode = Entry; - Entry = Entry->Next; - - switch (ThisNode->getKind()) { + + // We use a local ValueHandleBase as an iterator so that + // ValueHandles can add and remove themselves from the list without + // breaking our iteration. This is not really an AssertingVH; we + // just have to give ValueHandleBase some kind. + for (ValueHandleBase Iterator(Assert, *Entry); Entry; Entry = Iterator.Next) { + Iterator.RemoveFromUseList(); + Iterator.AddToExistingUseListAfter(Entry); + assert(Entry->Next == &Iterator && "Loop invariant broken."); + + switch (Entry->getKind()) { case Assert: -#ifndef NDEBUG // Only in -g mode... - cerr << "While deleting: " << *V->getType() << " %" << V->getNameStr() - << "\n"; -#endif - cerr << "An asserting value handle still pointed to this value!\n"; - abort(); + break; + case Tracking: + // Mark that this value has been deleted by setting it to an invalid Value + // pointer. + Entry->operator=(DenseMapInfo<Value *>::getTombstoneKey()); + break; case Weak: // Weak just goes to null, which will unlink it from the list. - ThisNode->operator=(0); + Entry->operator=(0); break; case Callback: // Forward to the subclass's implementation. - static_cast<CallbackVH*>(ThisNode)->deleted(); + static_cast<CallbackVH*>(Entry)->deleted(); break; } } - - // All callbacks and weak references should be dropped by now. - assert(!V->HasValueHandle && "All references to V were not removed?"); + + // All callbacks, weak references, and assertingVHs should be dropped by now. + if (V->HasValueHandle) { +#ifndef NDEBUG // Only in +Asserts mode... + errs() << "While deleting: " << *V->getType() << " %" << V->getNameStr() + << "\n"; + if (pImpl->ValueHandles[V]->getKind() == Assert) + llvm_unreachable("An asserting value handle still pointed to this" + " value!"); + +#endif + llvm_unreachable("All references to V were not removed?"); + } } void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { assert(Old->HasValueHandle &&"Should only be called if ValueHandles present"); assert(Old != New && "Changing value into itself!"); - + // Get the linked list base, which is guaranteed to exist since the // HasValueHandle flag is set. - ValueHandlesLock->reader_acquire(); - ValueHandleBase *Entry = (*ValueHandles)[Old]; - ValueHandlesLock->reader_release(); + LLVMContextImpl *pImpl = Old->getContext().pImpl; + ValueHandleBase *Entry = pImpl->ValueHandles[Old]; + assert(Entry && "Value bit set but no entries exist"); - - while (Entry) { - // Advance pointer to avoid invalidation. - ValueHandleBase *ThisNode = Entry; - Entry = Entry->Next; - - switch (ThisNode->getKind()) { + + // We use a local ValueHandleBase as an iterator so that + // ValueHandles can add and remove themselves from the list without + // breaking our iteration. This is not really an AssertingVH; we + // just have to give ValueHandleBase some kind. + for (ValueHandleBase Iterator(Assert, *Entry); Entry; Entry = Iterator.Next) { + Iterator.RemoveFromUseList(); + Iterator.AddToExistingUseListAfter(Entry); + assert(Entry->Next == &Iterator && "Loop invariant broken."); + + switch (Entry->getKind()) { case Assert: // Asserting handle does not follow RAUW implicitly. break; + case Tracking: + // Tracking goes to new value like a WeakVH. Note that this may make it + // something incompatible with its templated type. We don't want to have a + // virtual (or inline) interface to handle this though, so instead we make + // the TrackingVH accessors guarantee that a client never sees this value. + + // FALLTHROUGH case Weak: // Weak goes to the new value, which will unlink it from Old's list. - ThisNode->operator=(New); + Entry->operator=(New); break; case Callback: // Forward to the subclass's implementation. - static_cast<CallbackVH*>(ThisNode)->allUsesReplacedWith(New); + static_cast<CallbackVH*>(Entry)->allUsesReplacedWith(New); break; } } @@ -580,7 +606,7 @@ void User::replaceUsesOfWith(Value *From, Value *To) { if (From == To) return; // Duh what? assert((!isa<Constant>(this) || isa<GlobalValue>(this)) && - "Cannot call User::replaceUsesofWith on a constant!"); + "Cannot call User::replaceUsesOfWith on a constant!"); for (unsigned i = 0, E = getNumOperands(); i != E; ++i) if (getOperand(i) == From) { // Is This operand is pointing to oldval? @@ -590,4 +616,3 @@ void User::replaceUsesOfWith(Value *From, Value *To) { setOperand(i, To); // Fix it now... } } - diff --git a/lib/VMCore/ValueSymbolTable.cpp b/lib/VMCore/ValueSymbolTable.cpp index eee18a164c12..7765a98c1fd1 100644 --- a/lib/VMCore/ValueSymbolTable.cpp +++ b/lib/VMCore/ValueSymbolTable.cpp @@ -17,36 +17,20 @@ #include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; // Class destructor ValueSymbolTable::~ValueSymbolTable() { #ifndef NDEBUG // Only do this in -g mode... for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI) - cerr << "Value still in symbol table! Type = '" - << VI->getValue()->getType()->getDescription() << "' Name = '" - << VI->getKeyData() << "'\n"; + errs() << "Value still in symbol table! Type = '" + << VI->getValue()->getType()->getDescription() << "' Name = '" + << VI->getKeyData() << "'\n"; assert(vmap.empty() && "Values remain in symbol table!"); #endif } -// lookup a value - Returns null on failure... -// -Value *ValueSymbolTable::lookup(const std::string &Name) const { - const_iterator VI = vmap.find(Name.data(), Name.data() + Name.size()); - if (VI != vmap.end()) // We found the symbol - return VI->getValue(); - return 0; -} - -Value *ValueSymbolTable::lookup(const char *NameBegin, - const char *NameEnd) const { - const_iterator VI = vmap.find(NameBegin, NameEnd); - if (VI != vmap.end()) // We found the symbol - return VI->getValue(); - return 0; -} - // Insert a value into the symbol table with the specified name... // void ValueSymbolTable::reinsertValue(Value* V) { @@ -54,37 +38,38 @@ void ValueSymbolTable::reinsertValue(Value* V) { // Try inserting the name, assuming it won't conflict. if (vmap.insert(V->Name)) { - //DOUT << " Inserted value: " << V->Name << ": " << *V << "\n"; + //DEBUG(errs() << " Inserted value: " << V->Name << ": " << *V << "\n"); return; } // Otherwise, there is a naming conflict. Rename this value. - SmallString<128> UniqueName(V->getNameStart(), V->getNameEnd()); + SmallString<256> UniqueName(V->getName().begin(), V->getName().end()); // The name is too already used, just free it so we can allocate a new name. V->Name->Destroy(); unsigned BaseSize = UniqueName.size(); while (1) { - // Trim any suffix off. + // Trim any suffix off and append the next number. UniqueName.resize(BaseSize); - UniqueName.append_uint_32(++LastUnique); + raw_svector_ostream(UniqueName) << ++LastUnique; + // Try insert the vmap entry with this suffix. ValueName &NewName = - vmap.GetOrCreateValue(UniqueName.data(), - UniqueName.data() + UniqueName.size()); + vmap.GetOrCreateValue(StringRef(UniqueName.data(), + UniqueName.size())); if (NewName.getValue() == 0) { // Newly inserted name. Success! NewName.setValue(V); V->Name = &NewName; - //DEBUG(DOUT << " Inserted value: " << UniqueName << ": " << *V << "\n"); + //DEBUG(errs() << " Inserted value: " << UniqueName << ": " << *V << "\n"); return; } } } void ValueSymbolTable::removeValueName(ValueName *V) { - //DEBUG(DOUT << " Removing Value: " << V->getKeyData() << "\n"); + //DEBUG(errs() << " Removing Value: " << V->getKeyData() << "\n"); // Remove the value from the symbol table. vmap.remove(V); } @@ -92,33 +77,32 @@ void ValueSymbolTable::removeValueName(ValueName *V) { /// createValueName - This method attempts to create a value name and insert /// it into the symbol table with the specified name. If it conflicts, it /// auto-renames the name and returns that instead. -ValueName *ValueSymbolTable::createValueName(const char *NameStart, - unsigned NameLen, Value *V) { +ValueName *ValueSymbolTable::createValueName(const StringRef &Name, Value *V) { // In the common case, the name is not already in the symbol table. - ValueName &Entry = vmap.GetOrCreateValue(NameStart, NameStart+NameLen); + ValueName &Entry = vmap.GetOrCreateValue(Name); if (Entry.getValue() == 0) { Entry.setValue(V); - //DEBUG(DOUT << " Inserted value: " << Entry.getKeyData() << ": " + //DEBUG(errs() << " Inserted value: " << Entry.getKeyData() << ": " // << *V << "\n"); return &Entry; } // Otherwise, there is a naming conflict. Rename this value. - SmallString<128> UniqueName(NameStart, NameStart+NameLen); + SmallString<128> UniqueName(Name.begin(), Name.end()); while (1) { - // Trim any suffix off. - UniqueName.resize(NameLen); - UniqueName.append_uint_32(++LastUnique); + // Trim any suffix off and append the next number. + UniqueName.resize(Name.size()); + raw_svector_ostream(UniqueName) << ++LastUnique; // Try insert the vmap entry with this suffix. ValueName &NewName = - vmap.GetOrCreateValue(UniqueName.data(), - UniqueName.data() + UniqueName.size()); + vmap.GetOrCreateValue(StringRef(UniqueName.data(), + UniqueName.size())); if (NewName.getValue() == 0) { // Newly inserted name. Success! NewName.setValue(V); - //DEBUG(DOUT << " Inserted value: " << UniqueName << ": " << *V << "\n"); + //DEBUG(errs() << " Inserted value: " << UniqueName << ": " << *V << "\n"); return &NewName; } } @@ -128,10 +112,10 @@ ValueName *ValueSymbolTable::createValueName(const char *NameStart, // dump - print out the symbol table // void ValueSymbolTable::dump() const { - //DOUT << "ValueSymbolTable:\n"; + //DEBUG(errs() << "ValueSymbolTable:\n"); for (const_iterator I = begin(), E = end(); I != E; ++I) { - //DOUT << " '" << I->getKeyData() << "' = "; + //DEBUG(errs() << " '" << I->getKeyData() << "' = "); I->getValue()->dump(); - //DOUT << "\n"; + //DEBUG(errs() << "\n"); } } diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp index 2d207eea31db..7f9a6cde2d5c 100644 --- a/lib/VMCore/ValueTypes.cpp +++ b/lib/VMCore/ValueTypes.cpp @@ -1,4 +1,4 @@ -//===----------- ValueTypes.cpp - Implementation of MVT methods -----------===// +//===----------- ValueTypes.cpp - Implementation of EVT methods -----------===// // // The LLVM Compiler Infrastructure // @@ -13,62 +13,65 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/LLVMContext.h" #include "llvm/Type.h" #include "llvm/DerivedTypes.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; -MVT MVT::getExtendedIntegerVT(unsigned BitWidth) { - MVT VT; - VT.LLVMTy = IntegerType::get(BitWidth); +EVT EVT::getExtendedIntegerVT(LLVMContext &Context, unsigned BitWidth) { + EVT VT; + VT.LLVMTy = IntegerType::get(Context, BitWidth); assert(VT.isExtended() && "Type is not extended!"); return VT; } -MVT MVT::getExtendedVectorVT(MVT VT, unsigned NumElements) { - MVT ResultVT; - ResultVT.LLVMTy = VectorType::get(VT.getTypeForMVT(), NumElements); +EVT EVT::getExtendedVectorVT(LLVMContext &Context, EVT VT, + unsigned NumElements) { + EVT ResultVT; + ResultVT.LLVMTy = VectorType::get(VT.getTypeForEVT(Context), NumElements); assert(ResultVT.isExtended() && "Type is not extended!"); return ResultVT; } -bool MVT::isExtendedFloatingPoint() const { +bool EVT::isExtendedFloatingPoint() const { assert(isExtended() && "Type is not extended!"); return LLVMTy->isFPOrFPVector(); } -bool MVT::isExtendedInteger() const { +bool EVT::isExtendedInteger() const { assert(isExtended() && "Type is not extended!"); return LLVMTy->isIntOrIntVector(); } -bool MVT::isExtendedVector() const { +bool EVT::isExtendedVector() const { assert(isExtended() && "Type is not extended!"); return isa<VectorType>(LLVMTy); } -bool MVT::isExtended64BitVector() const { +bool EVT::isExtended64BitVector() const { return isExtendedVector() && getSizeInBits() == 64; } -bool MVT::isExtended128BitVector() const { +bool EVT::isExtended128BitVector() const { return isExtendedVector() && getSizeInBits() == 128; } -bool MVT::isExtended256BitVector() const { +bool EVT::isExtended256BitVector() const { return isExtendedVector() && getSizeInBits() == 256; } -MVT MVT::getExtendedVectorElementType() const { +EVT EVT::getExtendedVectorElementType() const { assert(isExtended() && "Type is not extended!"); - return MVT::getMVT(cast<VectorType>(LLVMTy)->getElementType()); + return EVT::getEVT(cast<VectorType>(LLVMTy)->getElementType()); } -unsigned MVT::getExtendedVectorNumElements() const { +unsigned EVT::getExtendedVectorNumElements() const { assert(isExtended() && "Type is not extended!"); return cast<VectorType>(LLVMTy)->getNumElements(); } -unsigned MVT::getExtendedSizeInBits() const { +unsigned EVT::getExtendedSizeInBits() const { assert(isExtended() && "Type is not extended!"); if (const IntegerType *ITy = dyn_cast<IntegerType>(LLVMTy)) return ITy->getBitWidth(); @@ -78,16 +81,16 @@ unsigned MVT::getExtendedSizeInBits() const { return 0; // Suppress warnings. } -/// getMVTString - This function returns value type as a string, e.g. "i32". -std::string MVT::getMVTString() const { - switch (V) { +/// getEVTString - This function returns value type as a string, e.g. "i32". +std::string EVT::getEVTString() const { + switch (V.SimpleTy) { default: if (isVector()) return "v" + utostr(getVectorNumElements()) + - getVectorElementType().getMVTString(); + getVectorElementType().getEVTString(); if (isInteger()) return "i" + utostr(getSizeInBits()); - assert(0 && "Invalid MVT!"); + llvm_unreachable("Invalid EVT!"); return "?"; case MVT::i1: return "i1"; case MVT::i8: return "i8"; @@ -113,14 +116,12 @@ std::string MVT::getMVTString() const { case MVT::v8i16: return "v8i16"; case MVT::v16i16: return "v16i16"; case MVT::v2i32: return "v2i32"; - case MVT::v3i32: return "v3i32"; case MVT::v4i32: return "v4i32"; case MVT::v8i32: return "v8i32"; case MVT::v1i64: return "v1i64"; case MVT::v2i64: return "v2i64"; case MVT::v4i64: return "v4i64"; case MVT::v2f32: return "v2f32"; - case MVT::v3f32: return "v3f32"; case MVT::v4f32: return "v4f32"; case MVT::v8f32: return "v8f32"; case MVT::v2f64: return "v2f64"; @@ -128,73 +129,72 @@ std::string MVT::getMVTString() const { } } -/// getTypeForMVT - This method returns an LLVM type corresponding to the -/// specified MVT. For integer types, this returns an unsigned type. Note +/// getTypeForEVT - This method returns an LLVM type corresponding to the +/// specified EVT. For integer types, this returns an unsigned type. Note /// that this will abort for types that cannot be represented. -const Type *MVT::getTypeForMVT() const { - switch (V) { +const Type *EVT::getTypeForEVT(LLVMContext &Context) const { + switch (V.SimpleTy) { default: assert(isExtended() && "Type is not extended!"); return LLVMTy; - case MVT::isVoid: return Type::VoidTy; - case MVT::i1: return Type::Int1Ty; - case MVT::i8: return Type::Int8Ty; - case MVT::i16: return Type::Int16Ty; - case MVT::i32: return Type::Int32Ty; - case MVT::i64: return Type::Int64Ty; - case MVT::i128: return IntegerType::get(128); - case MVT::f32: return Type::FloatTy; - case MVT::f64: return Type::DoubleTy; - case MVT::f80: return Type::X86_FP80Ty; - case MVT::f128: return Type::FP128Ty; - case MVT::ppcf128: return Type::PPC_FP128Ty; - case MVT::v2i8: return VectorType::get(Type::Int8Ty, 2); - case MVT::v4i8: return VectorType::get(Type::Int8Ty, 4); - case MVT::v8i8: return VectorType::get(Type::Int8Ty, 8); - case MVT::v16i8: return VectorType::get(Type::Int8Ty, 16); - case MVT::v32i8: return VectorType::get(Type::Int8Ty, 32); - case MVT::v2i16: return VectorType::get(Type::Int16Ty, 2); - case MVT::v4i16: return VectorType::get(Type::Int16Ty, 4); - case MVT::v8i16: return VectorType::get(Type::Int16Ty, 16); - case MVT::v16i16: return VectorType::get(Type::Int16Ty, 8); - case MVT::v2i32: return VectorType::get(Type::Int32Ty, 2); - case MVT::v3i32: return VectorType::get(Type::Int32Ty, 3); - case MVT::v4i32: return VectorType::get(Type::Int32Ty, 4); - case MVT::v8i32: return VectorType::get(Type::Int32Ty, 8); - case MVT::v1i64: return VectorType::get(Type::Int64Ty, 1); - case MVT::v2i64: return VectorType::get(Type::Int64Ty, 2); - case MVT::v4i64: return VectorType::get(Type::Int64Ty, 4); - case MVT::v2f32: return VectorType::get(Type::FloatTy, 2); - case MVT::v3f32: return VectorType::get(Type::FloatTy, 3); - case MVT::v4f32: return VectorType::get(Type::FloatTy, 4); - case MVT::v8f32: return VectorType::get(Type::FloatTy, 8); - case MVT::v2f64: return VectorType::get(Type::DoubleTy, 2); - case MVT::v4f64: return VectorType::get(Type::DoubleTy, 4); + case MVT::isVoid: return Type::getVoidTy(Context); + case MVT::i1: return Type::getInt1Ty(Context); + case MVT::i8: return Type::getInt8Ty(Context); + case MVT::i16: return Type::getInt16Ty(Context); + case MVT::i32: return Type::getInt32Ty(Context); + case MVT::i64: return Type::getInt64Ty(Context); + case MVT::i128: return IntegerType::get(Context, 128); + case MVT::f32: return Type::getFloatTy(Context); + case MVT::f64: return Type::getDoubleTy(Context); + case MVT::f80: return Type::getX86_FP80Ty(Context); + case MVT::f128: return Type::getFP128Ty(Context); + case MVT::ppcf128: return Type::getPPC_FP128Ty(Context); + case MVT::v2i8: return VectorType::get(Type::getInt8Ty(Context), 2); + case MVT::v4i8: return VectorType::get(Type::getInt8Ty(Context), 4); + case MVT::v8i8: return VectorType::get(Type::getInt8Ty(Context), 8); + case MVT::v16i8: return VectorType::get(Type::getInt8Ty(Context), 16); + case MVT::v32i8: return VectorType::get(Type::getInt8Ty(Context), 32); + case MVT::v2i16: return VectorType::get(Type::getInt16Ty(Context), 2); + case MVT::v4i16: return VectorType::get(Type::getInt16Ty(Context), 4); + case MVT::v8i16: return VectorType::get(Type::getInt16Ty(Context), 8); + case MVT::v16i16: return VectorType::get(Type::getInt16Ty(Context), 16); + case MVT::v2i32: return VectorType::get(Type::getInt32Ty(Context), 2); + case MVT::v4i32: return VectorType::get(Type::getInt32Ty(Context), 4); + case MVT::v8i32: return VectorType::get(Type::getInt32Ty(Context), 8); + case MVT::v1i64: return VectorType::get(Type::getInt64Ty(Context), 1); + case MVT::v2i64: return VectorType::get(Type::getInt64Ty(Context), 2); + case MVT::v4i64: return VectorType::get(Type::getInt64Ty(Context), 4); + case MVT::v2f32: return VectorType::get(Type::getFloatTy(Context), 2); + case MVT::v4f32: return VectorType::get(Type::getFloatTy(Context), 4); + case MVT::v8f32: return VectorType::get(Type::getFloatTy(Context), 8); + case MVT::v2f64: return VectorType::get(Type::getDoubleTy(Context), 2); + case MVT::v4f64: return VectorType::get(Type::getDoubleTy(Context), 4); + case MVT::Metadata: return Type::getMetadataTy(Context); } } -/// getMVT - Return the value type corresponding to the specified type. This +/// getEVT - Return the value type corresponding to the specified type. This /// returns all pointers as MVT::iPTR. If HandleUnknown is true, unknown types /// are returned as Other, otherwise they are invalid. -MVT MVT::getMVT(const Type *Ty, bool HandleUnknown){ +EVT EVT::getEVT(const Type *Ty, bool HandleUnknown){ switch (Ty->getTypeID()) { default: - if (HandleUnknown) return MVT::Other; - assert(0 && "Unknown type!"); + if (HandleUnknown) return MVT(MVT::Other); + llvm_unreachable("Unknown type!"); return MVT::isVoid; case Type::VoidTyID: return MVT::isVoid; case Type::IntegerTyID: - return getIntegerVT(cast<IntegerType>(Ty)->getBitWidth()); - case Type::FloatTyID: return MVT::f32; - case Type::DoubleTyID: return MVT::f64; - case Type::X86_FP80TyID: return MVT::f80; - case Type::FP128TyID: return MVT::f128; - case Type::PPC_FP128TyID: return MVT::ppcf128; - case Type::PointerTyID: return MVT::iPTR; + return getIntegerVT(Ty->getContext(), cast<IntegerType>(Ty)->getBitWidth()); + case Type::FloatTyID: return MVT(MVT::f32); + case Type::DoubleTyID: return MVT(MVT::f64); + case Type::X86_FP80TyID: return MVT(MVT::f80); + case Type::FP128TyID: return MVT(MVT::f128); + case Type::PPC_FP128TyID: return MVT(MVT::ppcf128); + case Type::PointerTyID: return MVT(MVT::iPTR); case Type::VectorTyID: { const VectorType *VTy = cast<VectorType>(Ty); - return getVectorVT(getMVT(VTy->getElementType(), false), + return getVectorVT(Ty->getContext(), getEVT(VTy->getElementType(), false), VTy->getNumElements()); } } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 10816e6248bc..75ea4c3e2f28 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -45,26 +45,27 @@ #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" -#include "llvm/MDNode.h" +#include "llvm/Metadata.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" +#include "llvm/TypeSymbolTable.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" #include "llvm/Support/InstVisitor.h" -#include "llvm/Support/Streams.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <sstream> #include <cstdarg> using namespace llvm; @@ -85,15 +86,15 @@ namespace { // Anonymous namespace for class for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { if (I->empty() || !I->back().isTerminator()) { - cerr << "Basic Block does not have terminator!\n"; - WriteAsOperand(*cerr, I, true); - cerr << "\n"; + errs() << "Basic Block does not have terminator!\n"; + WriteAsOperand(errs(), I, true); + errs() << "\n"; Broken = true; } } if (Broken) - abort(); + llvm_report_error("Broken module, no Basic Block terminator!"); return false; } @@ -106,8 +107,55 @@ PreVer("preverify", "Preliminary module verification"); static const PassInfo *const PreVerifyID = &PreVer; namespace { - struct VISIBILITY_HIDDEN - Verifier : public FunctionPass, InstVisitor<Verifier> { + class TypeSet : public AbstractTypeUser { + public: + TypeSet() {} + + /// Insert a type into the set of types. + bool insert(const Type *Ty) { + if (!Types.insert(Ty)) + return false; + if (Ty->isAbstract()) + Ty->addAbstractTypeUser(this); + return true; + } + + // Remove ourselves as abstract type listeners for any types that remain + // abstract when the TypeSet is destroyed. + ~TypeSet() { + for (SmallSetVector<const Type *, 16>::iterator I = Types.begin(), + E = Types.end(); I != E; ++I) { + const Type *Ty = *I; + if (Ty->isAbstract()) + Ty->removeAbstractTypeUser(this); + } + } + + // Abstract type user interface. + + /// Remove types from the set when refined. Do not insert the type it was + /// refined to because that type hasn't been verified yet. + void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { + Types.remove(OldTy); + OldTy->removeAbstractTypeUser(this); + } + + /// Stop listening for changes to a type which is no longer abstract. + void typeBecameConcrete(const DerivedType *AbsTy) { + AbsTy->removeAbstractTypeUser(this); + } + + void dump() const {} + + private: + SmallSetVector<const Type *, 16> Types; + + // Disallow copying. + TypeSet(const TypeSet &); + TypeSet &operator=(const TypeSet &); + }; + + struct Verifier : public FunctionPass, public InstVisitor<Verifier> { static char ID; // Pass ID, replacement for typeid bool Broken; // Is this module found to be broken? bool RealPass; // Are we not being run by a PassManager? @@ -115,7 +163,9 @@ namespace { // What to do if verification fails. Module *Mod; // Module we are verifying right now DominatorTree *DT; // Dominator Tree, caution can be null! - std::stringstream msgs; // A stringstream to collect messages + + std::string Messages; + raw_string_ostream MessagesStr; /// InstInThisBlock - when verifying a basic block, keep track of all of the /// instructions we have seen so far. This allows us to do efficient @@ -123,23 +173,26 @@ namespace { /// an instruction in the same block. SmallPtrSet<Instruction*, 16> InstsInThisBlock; + /// Types - keep track of the types that have been checked already. + TypeSet Types; + Verifier() : FunctionPass(&ID), Broken(false), RealPass(true), action(AbortProcessAction), - DT(0), msgs( std::ios::app | std::ios::out ) {} + DT(0), MessagesStr(Messages) {} explicit Verifier(VerifierFailureAction ctn) : FunctionPass(&ID), Broken(false), RealPass(true), action(ctn), DT(0), - msgs( std::ios::app | std::ios::out ) {} + MessagesStr(Messages) {} explicit Verifier(bool AB) : FunctionPass(&ID), Broken(false), RealPass(true), action( AB ? AbortProcessAction : PrintMessageAction), DT(0), - msgs( std::ios::app | std::ios::out ) {} + MessagesStr(Messages) {} explicit Verifier(DominatorTree &dt) : FunctionPass(&ID), Broken(false), RealPass(false), action(PrintMessageAction), - DT(&dt), msgs( std::ios::app | std::ios::out ) {} + DT(&dt), MessagesStr(Messages) {} bool doInitialization(Module &M) { @@ -205,19 +258,20 @@ namespace { /// bool abortIfBroken() { if (!Broken) return false; - msgs << "Broken module found, "; + MessagesStr << "Broken module found, "; switch (action) { - default: assert(0 && "Unknown action"); + default: llvm_unreachable("Unknown action"); case AbortProcessAction: - msgs << "compilation aborted!\n"; - cerr << msgs.str(); + MessagesStr << "compilation aborted!\n"; + errs() << MessagesStr.str(); + // Client should choose different reaction if abort is not desired abort(); case PrintMessageAction: - msgs << "verification continues.\n"; - cerr << msgs.str(); + MessagesStr << "verification continues.\n"; + errs() << MessagesStr.str(); return false; case ReturnStatusAction: - msgs << "compilation terminated.\n"; + MessagesStr << "compilation terminated.\n"; return true; } } @@ -231,9 +285,9 @@ namespace { void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); using InstVisitor<Verifier>::visit; - + void visit(Instruction &I); - + void visitTruncInst(TruncInst &I); void visitZExtInst(ZExtInst &I); void visitSExtInst(SExtInst &I); @@ -280,32 +334,32 @@ namespace { bool isReturnValue, const Value *V); void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs, const Value *V); + void VerifyType(const Type *Ty); void WriteValue(const Value *V) { if (!V) return; if (isa<Instruction>(V)) { - msgs << *V; + MessagesStr << *V; } else { - WriteAsOperand(msgs, V, true, Mod); - msgs << "\n"; + WriteAsOperand(MessagesStr, V, true, Mod); + MessagesStr << "\n"; } } void WriteType(const Type *T) { if (!T) return; - raw_os_ostream RO(msgs); - RO << ' '; - WriteTypeSymbolic(RO, T, Mod); + MessagesStr << ' '; + WriteTypeSymbolic(MessagesStr, T, Mod); } // CheckFailed - A check failed, so print out the condition and the message // that failed. This provides a nice place to put a breakpoint if you want // to see why something is not correct. - void CheckFailed(const std::string &Message, + void CheckFailed(const Twine &Message, const Value *V1 = 0, const Value *V2 = 0, const Value *V3 = 0, const Value *V4 = 0) { - msgs << Message << "\n"; + MessagesStr << Message.str() << "\n"; WriteValue(V1); WriteValue(V2); WriteValue(V3); @@ -313,14 +367,23 @@ namespace { Broken = true; } - void CheckFailed( const std::string& Message, const Value* V1, - const Type* T2, const Value* V3 = 0 ) { - msgs << Message << "\n"; + void CheckFailed(const Twine &Message, const Value *V1, + const Type *T2, const Value *V3 = 0) { + MessagesStr << Message.str() << "\n"; WriteValue(V1); WriteType(T2); WriteValue(V3); Broken = true; } + + void CheckFailed(const Twine &Message, const Type *T1, + const Type *T2 = 0, const Type *T3 = 0) { + MessagesStr << Message.str() << "\n"; + WriteType(T1); + WriteType(T2); + WriteType(T3); + Broken = true; + } }; } // End anonymous namespace @@ -359,14 +422,14 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(), "Global is marked as dllimport, but not external", &GV); - + Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV), "Only global variables can have appending linkage!", &GV); if (GV.hasAppendingLinkage()) { - GlobalVariable &GVar = cast<GlobalVariable>(GV); - Assert1(isa<ArrayType>(GVar.getType()->getElementType()), - "Only global arrays can have appending linkage!", &GV); + GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV); + Assert1(GVar && isa<ArrayType>(GVar->getType()->getElementType()), + "Only global arrays can have appending linkage!", GVar); } } @@ -376,26 +439,13 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { "Global variable initializer type does not match global " "variable type!", &GV); - // Verify that any metadata used in a global initializer points only to - // other globals. - if (MDNode *FirstNode = dyn_cast<MDNode>(GV.getInitializer())) { - SmallVector<const MDNode *, 4> NodesToAnalyze; - NodesToAnalyze.push_back(FirstNode); - while (!NodesToAnalyze.empty()) { - const MDNode *N = NodesToAnalyze.back(); - NodesToAnalyze.pop_back(); - - for (MDNode::const_elem_iterator I = N->elem_begin(), - E = N->elem_end(); I != E; ++I) - if (const Value *V = *I) { - if (const MDNode *Next = dyn_cast<MDNode>(V)) - NodesToAnalyze.push_back(Next); - else - Assert3(isa<Constant>(V), - "reference to instruction from global metadata node", - &GV, N, V); - } - } + // If the global has common linkage, it must have a zero initializer and + // cannot be constant. + if (GV.hasCommonLinkage()) { + Assert1(GV.getInitializer()->isNullValue(), + "'common' global must have a zero initializer!", &GV); + Assert1(!GV.isConstant(), "'common' global may not be marked constant!", + &GV); } } else { Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() || @@ -435,6 +485,8 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { } void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) { + for (TypeSymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I) + VerifyType(I->second); } // VerifyParameterAttrs - Check the given attributes for an argument or return @@ -525,16 +577,17 @@ void Verifier::VerifyFunctionAttrs(const FunctionType *FT, static bool VerifyAttributeCount(const AttrListPtr &Attrs, unsigned Params) { if (Attrs.isEmpty()) return true; - + unsigned LastSlot = Attrs.getNumSlots() - 1; unsigned LastIndex = Attrs.getSlot(LastSlot).Index; if (LastIndex <= Params || (LastIndex == (unsigned)~0 && (LastSlot == 0 || Attrs.getSlot(LastSlot - 1).Index <= Params))) return true; - + return false; } + // visitFunction - Verify that a function is ok. // void Verifier::visitFunction(Function &F) { @@ -542,15 +595,16 @@ void Verifier::visitFunction(Function &F) { const FunctionType *FT = F.getFunctionType(); unsigned NumArgs = F.arg_size(); + Assert1(!F.hasCommonLinkage(), "Functions may not have common linkage", &F); Assert2(FT->getNumParams() == NumArgs, "# formal arguments must match # of arguments for function type!", &F, FT); Assert1(F.getReturnType()->isFirstClassType() || - F.getReturnType() == Type::VoidTy || + F.getReturnType()->isVoidTy() || isa<StructType>(F.getReturnType()), "Functions cannot return aggregate values!", &F); - Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy, + Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(), "Invalid struct return type!", &F); const AttrListPtr &Attrs = F.getAttributes(); @@ -574,12 +628,9 @@ void Verifier::visitFunction(Function &F) { "Varargs functions must have C calling conventions!", &F); break; } - + bool isLLVMdotName = F.getName().size() >= 5 && F.getName().substr(0, 5) == "llvm."; - if (!isLLVMdotName) - Assert1(F.getReturnType() != Type::MetadataTy, - "Function may not return metadata unless it's an intrinsic", &F); // Check that the argument values match the function type for this function... unsigned i = 0; @@ -591,7 +642,7 @@ void Verifier::visitFunction(Function &F) { Assert1(I->getType()->isFirstClassType(), "Function arguments must have first-class types!", I); if (!isLLVMdotName) - Assert2(I->getType() != Type::MetadataTy, + Assert2(!I->getType()->isMetadataTy(), "Function takes metadata but isn't an intrinsic", I, &F); } @@ -609,9 +660,20 @@ void Verifier::visitFunction(Function &F) { Assert1(pred_begin(Entry) == pred_end(Entry), "Entry block to function must not have predecessors!", Entry); } + + // If this function is actually an intrinsic, verify that it is only used in + // direct call/invokes, never having its "address taken". + if (F.getIntrinsicID()) { + for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E;++UI){ + User *U = cast<User>(UI); + if ((isa<CallInst>(U) || isa<InvokeInst>(U)) && UI.getOperandNo() == 0) + continue; // Direct calls/invokes are ok. + + Assert1(0, "Invalid user of intrinsic instruction!", U); + } + } } - // verifyBasicBlock - Verify that a basic block is well formed... // void Verifier::visitBasicBlock(BasicBlock &BB) { @@ -628,7 +690,6 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { std::sort(Preds.begin(), Preds.end()); PHINode *PN; for (BasicBlock::iterator I = BB.begin(); (PN = dyn_cast<PHINode>(I));++I) { - // Ensure that PHI nodes have at least one entry! Assert1(PN->getNumIncomingValues() != 0, "PHI nodes must have at least one entry. If the block is dead, " @@ -676,7 +737,7 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); unsigned N = RI.getNumOperands(); - if (F->getReturnType() == Type::VoidTy) + if (F->getReturnType()->isVoidTy()) Assert2(N == 0, "Found return instr that returns non-void in Function of void " "return type!", &RI, F->getReturnType()); @@ -704,7 +765,7 @@ void Verifier::visitReturnInst(ReturnInst &RI) { CheckFailed("Function return type does not match operand " "type of return inst!", &RI, F->getReturnType()); } - + // Check to make sure that the return value has necessary properties for // terminators... visitTerminatorInst(RI); @@ -731,7 +792,6 @@ void Verifier::visitSelectInst(SelectInst &SI) { visitInstruction(SI); } - /// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of /// a pass, if any exist, it's an error. /// @@ -856,8 +916,8 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); Assert1(SrcVec == DstVec, "SIToFP source and dest must both be vector or scalar", &I); @@ -954,7 +1014,7 @@ void Verifier::visitBitCastInst(BitCastInst &I) { // However, you can't cast pointers to anything but pointers. Assert1(isa<PointerType>(DestTy) == isa<PointerType>(DestTy), "Bitcast requires both operands to be pointer or neither", &I); - Assert1(SrcBitSize == DestBitSize, "Bitcast requies types of same width", &I); + Assert1(SrcBitSize == DestBitSize, "Bitcast requires types of same width",&I); // Disallow aggregates. Assert1(!SrcTy->isAggregateType(), @@ -977,11 +1037,15 @@ void Verifier::visitPHINode(PHINode &PN) { "PHI nodes not grouped at top of basic block!", &PN, PN.getParent()); - // Check that all of the operands of the PHI node have the same type as the - // result. - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) + // Check that all of the values of the PHI node have the same type as the + // result, and that the incoming blocks are really basic blocks. + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { Assert1(PN.getType() == PN.getIncomingValue(i)->getType(), "PHI node operands are not the same type as the result!", &PN); + Assert1(isa<BasicBlock>(PN.getOperand( + PHINode::getOperandNumForIncomingBlock(i))), + "PHI node incoming block is not a BasicBlock!", &PN); + } // All other PHI node constraints are checked in the visitBasicBlock method. @@ -994,9 +1058,9 @@ void Verifier::VerifyCallSite(CallSite CS) { Assert1(isa<PointerType>(CS.getCalledValue()->getType()), "Called function must be a pointer!", I); const PointerType *FPTy = cast<PointerType>(CS.getCalledValue()->getType()); + Assert1(isa<FunctionType>(FPTy->getElementType()), "Called function is not pointer to function type!", I); - const FunctionType *FTy = cast<FunctionType>(FPTy->getElementType()); // Verify that the correct number of arguments are being passed @@ -1036,12 +1100,10 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify that there's no metadata unless it's a direct call to an intrinsic. if (!CS.getCalledFunction() || CS.getCalledFunction()->getName().size() < 5 || CS.getCalledFunction()->getName().substr(0, 5) != "llvm.") { - Assert1(FTy->getReturnType() != Type::MetadataTy, - "Only intrinsics may return metadata", I); for (FunctionType::param_iterator PI = FTy->param_begin(), PE = FTy->param_end(); PI != PE; ++PI) - Assert1(PI->get() != Type::MetadataTy, "Function has metadata parameter " - "but isn't an intrinsic", I); + Assert1(!PI->get()->isMetadataTy(), + "Function has metadata parameter but isn't an intrinsic", I); } visitInstruction(*I); @@ -1115,7 +1177,7 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { "Shift return type must be same as operands!", &B); break; default: - assert(0 && "Unknown BinaryOperator opcode!"); + llvm_unreachable("Unknown BinaryOperator opcode!"); } visitInstruction(B); @@ -1202,20 +1264,21 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { } void Verifier::visitLoadInst(LoadInst &LI) { - const Type *ElTy = - cast<PointerType>(LI.getOperand(0)->getType())->getElementType(); + const PointerType *PTy = dyn_cast<PointerType>(LI.getOperand(0)->getType()); + Assert1(PTy, "Load operand must be a pointer.", &LI); + const Type *ElTy = PTy->getElementType(); Assert2(ElTy == LI.getType(), "Load result type does not match pointer operand type!", &LI, ElTy); - Assert1(ElTy != Type::MetadataTy, "Can't load metadata!", &LI); visitInstruction(LI); } void Verifier::visitStoreInst(StoreInst &SI) { - const Type *ElTy = - cast<PointerType>(SI.getOperand(1)->getType())->getElementType(); + const PointerType *PTy = dyn_cast<PointerType>(SI.getOperand(1)->getType()); + Assert1(PTy, "Load operand must be a pointer.", &SI); + const Type *ElTy = PTy->getElementType(); Assert2(ElTy == SI.getOperand(0)->getType(), - "Stored value type does not match pointer operand type!", &SI, ElTy); - Assert1(ElTy != Type::MetadataTy, "Can't store metadata!", &SI); + "Stored value type does not match pointer operand type!", + &SI, ElTy); visitInstruction(SI); } @@ -1259,44 +1322,39 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB), "Only PHI nodes may reference their own value!", &I); } - + // Verify that if this is a terminator that it is at the end of the block. if (isa<TerminatorInst>(I)) Assert1(BB->getTerminator() == &I, "Terminator not at end of block!", &I); - // Check that void typed values don't have names - Assert1(I.getType() != Type::VoidTy || !I.hasName(), + Assert1(!I.getType()->isVoidTy() || !I.hasName(), "Instruction has a name, but provides a void value!", &I); // Check that the return value of the instruction is either void or a legal // value type. - Assert1(I.getType() == Type::VoidTy || I.getType()->isFirstClassType() - || ((isa<CallInst>(I) || isa<InvokeInst>(I)) - && isa<StructType>(I.getType())), + Assert1(I.getType()->isVoidTy() || + I.getType()->isFirstClassType(), "Instruction returns a non-scalar type!", &I); - // Check that the instruction doesn't produce metadata or metadata*. Calls - // all already checked against the callee type. - Assert1(I.getType() != Type::MetadataTy || + // Check that the instruction doesn't produce metadata. Calls are already + // checked against the callee type. + Assert1(!I.getType()->isMetadataTy() || isa<CallInst>(I) || isa<InvokeInst>(I), "Invalid use of metadata!", &I); - if (const PointerType *PTy = dyn_cast<PointerType>(I.getType())) - Assert1(PTy->getElementType() != Type::MetadataTy, - "Instructions may not produce pointer to metadata.", &I); - - // Check that all uses of the instruction, if they are instructions // themselves, actually have parent basic blocks. If the use is not an // instruction, it is an error! for (User::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE; ++UI) { - Assert1(isa<Instruction>(*UI), "Use of instruction is not an instruction!", - *UI); - Instruction *Used = cast<Instruction>(*UI); - Assert2(Used->getParent() != 0, "Instruction referencing instruction not" - " embedded in a basic block!", &I, Used); + if (Instruction *Used = dyn_cast<Instruction>(*UI)) + Assert2(Used->getParent() != 0, "Instruction referencing instruction not" + " embedded in a basic block!", &I, Used); + else { + CheckFailed("Use of instruction is not an instruction!", *UI); + return; + } } for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { @@ -1308,11 +1366,6 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(0, "Instruction operands must be first-class values!", &I); } - if (const PointerType *PTy = - dyn_cast<PointerType>(I.getOperand(i)->getType())) - Assert1(PTy->getElementType() != Type::MetadataTy, - "Invalid use of metadata pointer.", &I); - if (Function *F = dyn_cast<Function>(I.getOperand(i))) { // Check to make sure that the "address of" an intrinsic function is never // taken. @@ -1346,7 +1399,9 @@ void Verifier::visitInstruction(Instruction &I) { // value in the predecessor basic blocks they correspond to. BasicBlock *UseBlock = BB; if (isa<PHINode>(I)) - UseBlock = cast<BasicBlock>(I.getOperand(i+1)); + UseBlock = dyn_cast<BasicBlock>(I.getOperand(i+1)); + Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB", + Op, &I); if (isa<PHINode>(I) && UseBlock == OpBlock) { // Special case of a phi node in the normal destination or the unwind @@ -1379,9 +1434,9 @@ void Verifier::visitInstruction(Instruction &I) { } else if (isa<PHINode>(I)) { // PHI nodes are more difficult than other nodes because they actually // "use" the value in the predecessor basic blocks they correspond to. - BasicBlock *PredBB = cast<BasicBlock>(I.getOperand(i+1)); - Assert2(DT->dominates(OpBlock, PredBB) || - !DT->isReachableFromEntry(PredBB), + BasicBlock *PredBB = dyn_cast<BasicBlock>(I.getOperand(i+1)); + Assert2(PredBB && (DT->dominates(OpBlock, PredBB) || + !DT->isReachableFromEntry(PredBB)), "Instruction does not dominate all uses!", Op, &I); } else { if (OpBlock == BB) { @@ -1402,6 +1457,61 @@ void Verifier::visitInstruction(Instruction &I) { } } InstsInThisBlock.insert(&I); + + VerifyType(I.getType()); +} + +/// VerifyType - Verify that a type is well formed. +/// +void Verifier::VerifyType(const Type *Ty) { + if (!Types.insert(Ty)) return; + + switch (Ty->getTypeID()) { + case Type::FunctionTyID: { + const FunctionType *FTy = cast<FunctionType>(Ty); + + const Type *RetTy = FTy->getReturnType(); + Assert2(FunctionType::isValidReturnType(RetTy), + "Function type with invalid return type", RetTy, FTy); + VerifyType(RetTy); + + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) { + const Type *ElTy = FTy->getParamType(i); + Assert2(FunctionType::isValidArgumentType(ElTy), + "Function type with invalid parameter type", ElTy, FTy); + VerifyType(ElTy); + } + } break; + case Type::StructTyID: { + const StructType *STy = cast<StructType>(Ty); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + const Type *ElTy = STy->getElementType(i); + Assert2(StructType::isValidElementType(ElTy), + "Structure type with invalid element type", ElTy, STy); + VerifyType(ElTy); + } + } break; + case Type::ArrayTyID: { + const ArrayType *ATy = cast<ArrayType>(Ty); + Assert1(ArrayType::isValidElementType(ATy->getElementType()), + "Array type with invalid element type", ATy); + VerifyType(ATy->getElementType()); + } break; + case Type::PointerTyID: { + const PointerType *PTy = cast<PointerType>(Ty); + Assert1(PointerType::isValidElementType(PTy->getElementType()), + "Pointer type with invalid element type", PTy); + VerifyType(PTy->getElementType()); + } break; + case Type::VectorTyID: { + const VectorType *VTy = cast<VectorType>(Ty); + Assert1(VectorType::isValidElementType(VTy->getElementType()), + "Vector type with invalid element type", VTy); + VerifyType(VTy->getElementType()); + } break; + default: + break; + } } // Flags used by TableGen to mark intrinsic parameters with the @@ -1415,11 +1525,11 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Function *IF = CI.getCalledFunction(); Assert1(IF->isDeclaration(), "Intrinsic functions should never be defined!", IF); - + #define GET_INTRINSIC_VERIFIER #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_VERIFIER - + switch (ID) { default: break; @@ -1446,7 +1556,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(isa<Constant>(CI.getOperand(2)), "llvm.gcroot parameter #2 must be a constant.", &CI); } - + Assert1(CI.getParent()->getParent()->hasGC(), "Enclosing function does not use GC.", &CI); break; @@ -1468,6 +1578,17 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "llvm.stackprotector parameter #2 must resolve to an alloca.", &CI); break; + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + case Intrinsic::invariant_start: + Assert1(isa<ConstantInt>(CI.getOperand(1)), + "size argument of memory use markers must be a constant integer", + &CI); + break; + case Intrinsic::invariant_end: + Assert1(isa<ConstantInt>(CI.getOperand(2)), + "llvm.invariant.end parameter #2 must be a constant integer", &CI); + break; } } @@ -1541,9 +1662,9 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, return false; } } else { - if (Ty != FTy->getParamType(Match - 1)) { + if (Ty != FTy->getParamType(Match - NumRets)) { CheckFailed(IntrinsicParam(ArgNo, NumRets) + " does not " - "match parameter %" + utostr(Match - 1) + ".", F); + "match parameter %" + utostr(Match - NumRets) + ".", F); return false; } } @@ -1584,7 +1705,13 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, if (EltTy != Ty) Suffix += "v" + utostr(NumElts); - Suffix += MVT::getMVT(EltTy).getMVTString(); + Suffix += EVT::getEVT(EltTy).getEVTString(); + } else if (VT == MVT::vAny) { + if (!VTy) { + CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a vector type.", F); + return false; + } + Suffix += ".v" + utostr(NumElts) + EVT::getEVT(EltTy).getEVTString(); } else if (VT == MVT::iPTR) { if (!isa<PointerType>(Ty)) { CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a " @@ -1597,17 +1724,17 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, // allow either case to be legal. if (const PointerType* PTyp = dyn_cast<PointerType>(Ty)) { Suffix += ".p" + utostr(PTyp->getAddressSpace()) + - MVT::getMVT(PTyp->getElementType()).getMVTString(); + EVT::getEVT(PTyp->getElementType()).getEVTString(); } else { CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is not a " "pointer and a pointer is required.", F); return false; } - } else if (MVT((MVT::SimpleValueType)VT).isVector()) { - MVT VVT = MVT((MVT::SimpleValueType)VT); + } else if (EVT((MVT::SimpleValueType)VT).isVector()) { + EVT VVT = EVT((MVT::SimpleValueType)VT); // If this is a vector argument, verify the number and type of elements. - if (VVT.getVectorElementType() != MVT::getMVT(EltTy)) { + if (VVT.getVectorElementType() != EVT::getEVT(EltTy)) { CheckFailed("Intrinsic prototype has incorrect vector element type!", F); return false; } @@ -1617,7 +1744,8 @@ bool Verifier::PerformTypeCheck(Intrinsic::ID ID, Function *F, const Type *Ty, "vector elements!", F); return false; } - } else if (MVT((MVT::SimpleValueType)VT).getTypeForMVT() != EltTy) { + } else if (EVT((MVT::SimpleValueType)VT).getTypeForEVT(Ty->getContext()) != + EltTy) { CheckFailed(IntrinsicParam(ArgNo, NumRets) + " is wrong!", F); return false; } else if (EltTy != Ty) { @@ -1638,7 +1766,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, va_list VA; va_start(VA, ParamNum); const FunctionType *FTy = F->getFunctionType(); - + // For overloaded intrinsics, the Suffix of the function name must match the // types of the arguments. This variable keeps track of the expected // suffix, to be checked at the end. @@ -1739,10 +1867,8 @@ bool llvm::verifyModule(const Module &M, VerifierFailureAction action, Verifier *V = new Verifier(action); PM.add(V); PM.run(const_cast<Module&>(M)); - + if (ErrorInfo && V->Broken) - *ErrorInfo = V->msgs.str(); + *ErrorInfo = V->MessagesStr.str(); return V->Broken; } - -// vim: sw=2 |