diff options
author | dim <dim@FreeBSD.org> | 2011-07-17 15:36:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-07-17 15:36:56 +0000 |
commit | 1176aa52646fe641a4243a246aa7f960c708a274 (patch) | |
tree | c8086addb211fa670a9d2b1038d8c2e453229755 /lib/VMCore | |
parent | ece02cd5829cea836e9365b0845a8ef042d17b0a (diff) | |
download | FreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.zip FreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.tar.gz |
Vendor import of llvm trunk r135360:
http://llvm.org/svn/llvm-project/llvm/trunk@135360
Diffstat (limited to 'lib/VMCore')
31 files changed, 1372 insertions, 4193 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 844284d..94794c3 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -26,13 +26,11 @@ #include "llvm/Operator.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" @@ -42,11 +40,6 @@ #include <cctype> using namespace llvm; -static cl::opt<bool> -EnableDebugInfoComment("enable-debug-info-comment", cl::Hidden, - cl::desc("Enable debug info comments")); - - // Make virtual table appear in this compilation unit. AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} @@ -140,60 +133,60 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { // TypePrinting Class: Type printing machinery //===----------------------------------------------------------------------===// -static DenseMap<const Type *, std::string> &getTypeNamesMap(void *M) { - return *static_cast<DenseMap<const Type *, std::string>*>(M); -} - -void TypePrinting::clear() { - getTypeNamesMap(TypeNames).clear(); -} +/// TypePrinting - Type printing machinery. +namespace { +class TypePrinting { + TypePrinting(const TypePrinting &); // DO NOT IMPLEMENT + void operator=(const TypePrinting&); // DO NOT IMPLEMENT +public: -bool TypePrinting::hasTypeName(const Type *Ty) const { - return getTypeNamesMap(TypeNames).count(Ty); -} + /// NamedTypes - The named types that are used by the current module. + std::vector<StructType*> NamedTypes; + + /// NumberedTypes - The numbered types, along with their value. + DenseMap<StructType*, unsigned> NumberedTypes; + -void TypePrinting::addTypeName(const Type *Ty, const std::string &N) { - getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N)); -} + TypePrinting() {} + ~TypePrinting() {} + + void incorporateTypes(const Module &M); + + void print(Type *Ty, raw_ostream &OS); + + void printStructBody(StructType *Ty, raw_ostream &OS); +}; +} // end anonymous namespace. -TypePrinting::TypePrinting() { - TypeNames = new DenseMap<const Type *, std::string>(); +void TypePrinting::incorporateTypes(const Module &M) { + M.findUsedStructTypes(NamedTypes); + + // The list of struct types we got back includes all the struct types, split + // the unnamed ones out to a numbering and remove the anonymous structs. + unsigned NextNumber = 0; + + std::vector<StructType*>::iterator NextToUse = NamedTypes.begin(), I, E; + for (I = NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) { + StructType *STy = *I; + + // Ignore anonymous types. + if (STy->isAnonymous()) + continue; + + if (STy->getName().empty()) + NumberedTypes[STy] = NextNumber++; + else + *NextToUse++ = STy; + } + + NamedTypes.erase(NextToUse, NamedTypes.end()); } -TypePrinting::~TypePrinting() { - delete &getTypeNamesMap(TypeNames); -} /// CalcTypeName - Write the specified type to the specified raw_ostream, making /// use of type names or up references to shorten the type name where possible. -void TypePrinting::CalcTypeName(const Type *Ty, - SmallVectorImpl<const Type *> &TypeStack, - raw_ostream &OS, bool IgnoreTopLevelName) { - // Check to see if the type is named. - if (!IgnoreTopLevelName) { - DenseMap<const Type *, std::string> &TM = getTypeNamesMap(TypeNames); - DenseMap<const Type *, std::string>::iterator I = TM.find(Ty); - if (I != TM.end()) { - OS << I->second; - 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. - if (Slot < CurSize) { - OS << '\\' << unsigned(CurSize-Slot); // Here's the upreference - return; - } - - TypeStack.push_back(Ty); // Recursive case: Add us to the stack.. - +void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; break; case Type::FloatTyID: OS << "float"; break; @@ -206,259 +199,96 @@ void TypePrinting::CalcTypeName(const Type *Ty, case Type::X86_MMXTyID: OS << "x86_mmx"; break; case Type::IntegerTyID: OS << 'i' << cast<IntegerType>(Ty)->getBitWidth(); - break; + return; case Type::FunctionTyID: { - const FunctionType *FTy = cast<FunctionType>(Ty); - CalcTypeName(FTy->getReturnType(), TypeStack, OS); + FunctionType *FTy = cast<FunctionType>(Ty); + print(FTy->getReturnType(), OS); OS << " ("; for (FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end(); I != E; ++I) { if (I != FTy->param_begin()) OS << ", "; - CalcTypeName(*I, TypeStack, OS); + print(*I, OS); } if (FTy->isVarArg()) { if (FTy->getNumParams()) OS << ", "; OS << "..."; } OS << ')'; - break; + return; } case Type::StructTyID: { - const StructType *STy = cast<StructType>(Ty); - if (STy->isPacked()) - OS << '<'; - OS << '{'; - for (StructType::element_iterator I = STy->element_begin(), - E = STy->element_end(); I != E; ++I) { - OS << ' '; - CalcTypeName(*I, TypeStack, OS); - if (llvm::next(I) == STy->element_end()) - OS << ' '; - else - OS << ','; - } - OS << '}'; - if (STy->isPacked()) - OS << '>'; - break; + StructType *STy = cast<StructType>(Ty); + + if (STy->isAnonymous()) + return printStructBody(STy, OS); + + if (!STy->getName().empty()) + return PrintLLVMName(OS, STy->getName(), LocalPrefix); + + DenseMap<StructType*, unsigned>::iterator I = NumberedTypes.find(STy); + if (I != NumberedTypes.end()) + OS << '%' << I->second; + else // Not enumerated, print the hex address. + OS << "%\"type 0x" << STy << '\"'; + return; } case Type::PointerTyID: { - const PointerType *PTy = cast<PointerType>(Ty); - CalcTypeName(PTy->getElementType(), TypeStack, OS); + PointerType *PTy = cast<PointerType>(Ty); + print(PTy->getElementType(), OS); if (unsigned AddressSpace = PTy->getAddressSpace()) OS << " addrspace(" << AddressSpace << ')'; OS << '*'; - break; + return; } case Type::ArrayTyID: { - const ArrayType *ATy = cast<ArrayType>(Ty); + ArrayType *ATy = cast<ArrayType>(Ty); OS << '[' << ATy->getNumElements() << " x "; - CalcTypeName(ATy->getElementType(), TypeStack, OS); + print(ATy->getElementType(), OS); OS << ']'; - break; + return; } case Type::VectorTyID: { - const VectorType *PTy = cast<VectorType>(Ty); + VectorType *PTy = cast<VectorType>(Ty); OS << "<" << PTy->getNumElements() << " x "; - CalcTypeName(PTy->getElementType(), TypeStack, OS); + print(PTy->getElementType(), OS); OS << '>'; - break; + return; } - case Type::OpaqueTyID: - OS << "opaque"; - break; default: OS << "<unrecognized-type>"; - break; + return; } - - TypeStack.pop_back(); // Remove self from stack. } -/// printTypeInt - The internal guts of printing out a type that has a -/// potentially named portion. -/// -void TypePrinting::print(const Type *Ty, raw_ostream &OS, - bool IgnoreTopLevelName) { - // Check to see if the type is named. - DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames); - if (!IgnoreTopLevelName) { - DenseMap<const Type*, std::string>::iterator I = TM.find(Ty); - if (I != TM.end()) { - OS << I->second; - return; - } +void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { + if (STy->isOpaque()) { + OS << "opaque"; + 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(); - - // Cache type name for later use. - if (!IgnoreTopLevelName) - TM.insert(std::make_pair(Ty, TypeOS.str())); -} - -namespace { - class TypeFinder { - // To avoid walking constant expressions multiple times and other IR - // 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. - const TypeSymbolTable &ST = M.getTypeSymbolTable(); - 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) { - IncorporateType(I->getType()); - 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(), - E = BB->end(); II != E; ++II) { - const Instruction &I = *II; - // Incorporate the type of the instruction and all its operands. - IncorporateType(I.getType()); - for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); - OI != OE; ++OI) - IncorporateValue(*OI); - } - } - } - - 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 (((Ty->isStructTy() && cast<StructType>(Ty)->getNumElements()) - || Ty->isOpaqueTy()) && !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); - } - - /// 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(), - E = C->op_end(); I != E;++I) - IncorporateValue(*I); - } - }; -} // end anonymous 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, - 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)) { - const Type *PETy = PTy->getElementType(); - if ((PETy->isPrimitiveType() || PETy->isIntegerTy()) && - !PETy->isOpaqueTy()) - continue; + + if (STy->isPacked()) + OS << '<'; + + if (STy->getNumElements() == 0) { + OS << "{}"; + } else { + StructType::element_iterator I = STy->element_begin(); + OS << "{ "; + print(*I++, OS); + for (StructType::element_iterator E = STy->element_end(); I != E; ++I) { + OS << ", "; + print(*I, OS); } - - // Likewise don't insert primitives either. - if (Ty->isIntegerTy() || Ty->isPrimitiveType()) - continue; - - // Get the name as a string and insert it into TypeNames. - std::string NameStr; - raw_string_ostream NameROS(NameStr); - formatted_raw_ostream NameOS(NameROS); - PrintLLVMName(NameOS, TI->first, LocalPrefix); - NameOS.flush(); - TP.addTypeName(Ty, NameStr); + + OS << " }"; } - - // 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 - // it shrinks complex recursive structure types substantially in some cases. - TypeFinder(TP, NumberedTypes).Run(*M); + if (STy->isPacked()) + OS << '>'; } -/// WriteTypeSymbolic - This attempts to write the specified type as a symbolic -/// type, iff there is an entry in the modules symbol table for the specified -/// type or one of it's component types. -/// -void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M) { - TypePrinting Printer; - std::vector<const Type*> NumberedTypes; - AddModuleTypesToPrinter(Printer, NumberedTypes, M); - Printer.print(Ty, OS); -} //===----------------------------------------------------------------------===// // SlotTracker Class: Enumerate slot numbers for unnamed values @@ -481,11 +311,11 @@ private: const Function* TheFunction; bool FunctionProcessed; - /// mMap - The TypePlanes map for the module level data. + /// mMap - The slot map for the module level data. ValueMap mMap; unsigned mNext; - /// fMap - The TypePlanes map for the function level data. + /// fMap - The slot map for the function level data. ValueMap fMap; unsigned fNext; @@ -706,7 +536,7 @@ int SlotTracker::getGlobalSlot(const GlobalValue *V) { // Check for uninitialized state and do lazy initialization. initialize(); - // Find the type plane in the module map + // Find the value in the module map ValueMap::iterator MI = mMap.find(V); return MI == mMap.end() ? -1 : (int)MI->second; } @@ -716,7 +546,7 @@ int SlotTracker::getMetadataSlot(const MDNode *N) { // Check for uninitialized state and do lazy initialization. initialize(); - // Find the type plane in the module map + // Find the MDNode in the module map mdn_iterator MI = mdnMap.find(N); return MI == mdnMap.end() ? -1 : (int)MI->second; } @@ -978,7 +808,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, // As a special case, print the array as a string if it is an array of // i8 with ConstantInt values. // - const Type *ETy = CA->getType()->getElementType(); + Type *ETy = CA->getType()->getElementType(); if (CA->isString()) { Out << "c\""; PrintEscapedString(CA->getAsString(), Out); @@ -1035,7 +865,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { - const Type *ETy = CP->getType()->getElementType(); + Type *ETy = CP->getType()->getElementType(); assert(CP->getNumOperands() > 0 && "Number of operands for a PackedConst must be > 0"); Out << '<'; @@ -1233,8 +1063,8 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, if (Context == 0) Context = getModuleFromVal(V); TypePrinting TypePrinter; - std::vector<const Type*> NumberedTypes; - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, Context); + if (Context) + TypePrinter.incorporateTypes(*Context); if (PrintType) { TypePrinter.print(V->getType(), Out); Out << ' '; @@ -1251,14 +1081,14 @@ class AssemblyWriter { const Module *TheModule; TypePrinting TypePrinter; AssemblyAnnotationWriter *AnnotationWriter; - std::vector<const Type*> NumberedTypes; public: inline AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW) : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) { - AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M); + if (M) + TypePrinter.incorporateTypes(*M); } void printMDNodeBody(const MDNode *MD); @@ -1271,7 +1101,7 @@ public: void writeAllMDNodes(); - void printTypeSymbolTable(const TypeSymbolTable &ST); + void printTypeIdentities(); void printGlobal(const GlobalVariable *GV); void printAlias(const GlobalAlias *GV); void printFunction(const Function *F); @@ -1366,9 +1196,7 @@ void AssemblyWriter::printModule(const Module *M) { Out << " ]"; } - // Loop over the symbol table, emitting all id'd types. - if (!M->getTypeSymbolTable().empty() || !NumberedTypes.empty()) Out << '\n'; - printTypeSymbolTable(M->getTypeSymbolTable()); + printTypeIdentities(); // Output all globals. if (!M->global_empty()) Out << '\n'; @@ -1401,7 +1229,25 @@ void AssemblyWriter::printModule(const Module *M) { } void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) { - Out << "!" << NMD->getName() << " = !{"; + Out << '!'; + StringRef Name = NMD->getName(); + if (Name.empty()) { + Out << "<empty name> "; + } else { + if (isalpha(Name[0]) || Name[0] == '-' || Name[0] == '$' || + Name[0] == '.' || Name[0] == '_') + Out << Name[0]; + else + Out << '\\' << hexdigit(Name[0] >> 4) << hexdigit(Name[0] & 0x0F); + for (unsigned i = 1, e = Name.size(); i != e; ++i) { + unsigned char C = Name[i]; + if (isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_') + Out << C; + else + Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); + } + } + Out << " = !{"; for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { if (i) Out << ", "; int Slot = Machine.getMetadataSlot(NMD->getOperand(i)); @@ -1508,7 +1354,10 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { const Constant *Aliasee = GA->getAliasee(); - if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { + if (Aliasee == 0) { + TypePrinter.print(GA->getType(), Out); + Out << " <<NULL ALIASEE>>"; + } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { TypePrinter.print(GV->getType(), Out); Out << ' '; PrintLLVMName(Out, GV); @@ -1534,26 +1383,40 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << '\n'; } -void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) { +void AssemblyWriter::printTypeIdentities() { + if (TypePrinter.NumberedTypes.empty() && + TypePrinter.NamedTypes.empty()) + return; + + Out << '\n'; + + // We know all the numbers that each type is used and we know that it is a + // dense assignment. Convert the map to an index table. + std::vector<StructType*> NumberedTypes(TypePrinter.NumberedTypes.size()); + for (DenseMap<StructType*, unsigned>::iterator I = + TypePrinter.NumberedTypes.begin(), E = TypePrinter.NumberedTypes.end(); + I != E; ++I) { + assert(I->second < NumberedTypes.size() && "Didn't get a dense numbering?"); + NumberedTypes[I->second] = I->first; + } + // Emit all numbered types. for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) { 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); + TypePrinter.printStructBody(NumberedTypes[i], Out); Out << '\n'; } - - // Print the named types. - for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end(); - TI != TE; ++TI) { - PrintLLVMName(Out, TI->first, LocalPrefix); + + for (unsigned i = 0, e = TypePrinter.NamedTypes.size(); i != e; ++i) { + PrintLLVMName(Out, TypePrinter.NamedTypes[i]->getName(), LocalPrefix); Out << " = type "; // Make sure we print out at least one level of the type structure, so // that we do not get %FILE = type %FILE - TypePrinter.printAtLeastOneLevel(TI->second, Out); + TypePrinter.printStructBody(TypePrinter.NamedTypes[i], Out); Out << '\n'; } } @@ -1735,18 +1598,6 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out); } -/// printDebugLoc - Print DebugLoc. -static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { - OS << DL.getLine() << ":" << DL.getCol(); - if (MDNode *N = DL.getInlinedAt(getGlobalContext())) { - DebugLoc IDL = DebugLoc::getFromDILocation(N); - if (!IDL.isUnknown()) { - OS << "@"; - printDebugLoc(IDL,OS); - } - } -} - /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. /// @@ -1754,43 +1605,6 @@ void AssemblyWriter::printInfoComment(const Value &V) { if (AnnotationWriter) { AnnotationWriter->printInfoComment(V, Out); return; - } else if (EnableDebugInfoComment) { - bool Padded = false; - if (const Instruction *I = dyn_cast<Instruction>(&V)) { - const DebugLoc &DL = I->getDebugLoc(); - if (!DL.isUnknown()) { - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - Out << " [debug line = "; - printDebugLoc(DL,Out); - Out << "]"; - } - if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) { - const MDNode *Var = DDI->getVariable(); - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - if (Var && Var->getNumOperands() >= 2) - if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2))) - Out << " [debug variable = " << MDS->getString() << "]"; - } - else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) { - const MDNode *Var = DVI->getVariable(); - if (!Padded) { - Out.PadToColumn(50); - Padded = true; - Out << ";"; - } - if (Var && Var->getNumOperands() >= 2) - if (MDString *MDS = dyn_cast_or_null<MDString>(Var->getOperand(2))) - Out << " [debug variable = " << MDS->getString() << "]"; - } - } } } @@ -1873,16 +1687,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(i), true); } Out << ']'; - } else if (isa<PHINode>(I)) { + } else if (const PHINode *PN = dyn_cast<PHINode>(&I)) { Out << ' '; TypePrinter.print(I.getType(), Out); Out << ' '; - for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) { + for (unsigned op = 0, Eop = PN->getNumIncomingValues(); op < Eop; ++op) { if (op) Out << ", "; Out << "[ "; - writeOperand(I.getOperand(op ), false); Out << ", "; - writeOperand(I.getOperand(op+1), false); Out << " ]"; + writeOperand(PN->getIncomingValue(op), false); Out << ", "; + writeOperand(PN->getIncomingBlock(op), false); Out << " ]"; } } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) { Out << ' '; @@ -1916,9 +1730,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { } Operand = CI->getCalledValue(); - const PointerType *PTy = cast<PointerType>(Operand->getType()); - const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + PointerType *PTy = cast<PointerType>(Operand->getType()); + FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = CI->getAttributes(); if (PAL.getRetAttributes() != Attribute::None) @@ -1949,9 +1763,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << ' ' << Attribute::getAsString(PAL.getFnAttributes()); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { Operand = II->getCalledValue(); - const PointerType *PTy = cast<PointerType>(Operand->getType()); - const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); - const Type *RetTy = FTy->getReturnType(); + PointerType *PTy = cast<PointerType>(Operand->getType()); + FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + Type *RetTy = FTy->getReturnType(); const AttrListPtr &PAL = II->getAttributes(); // Print the calling convention being used. @@ -2034,7 +1848,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // omit the type from all but the first operand. If the instruction has // different type operands (for example br), then they are all printed. bool PrintAllTypes = false; - const Type *TheType = Operand->getType(); + Type *TheType = Operand->getType(); // Select, Store and ShuffleVector always print all types. if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I) @@ -2154,7 +1968,15 @@ void Type::print(raw_ostream &OS) const { OS << "<null Type>"; return; } - TypePrinting().print(this, OS); + TypePrinting TP; + TP.print(const_cast<Type*>(this), OS); + + // If the type is a named struct type, print the body as well. + if (StructType *STy = dyn_cast<StructType>(const_cast<Type*>(this))) + if (!STy->isAnonymous()) { + OS << " = type "; + TP.printStructBody(STy, OS); + } } void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { @@ -2210,14 +2032,7 @@ void Value::printCustom(raw_ostream &OS) const { void Value::dump() const { print(dbgs()); dbgs() << '\n'; } // Type::dump - allow easy printing of Types from the debugger. -// This one uses type names from the given context module -void Type::dump(const Module *Context) const { - WriteTypeSymbolic(dbgs(), this, Context); - dbgs() << '\n'; -} - -// Type::dump - allow easy printing of Types from the debugger. -void Type::dump() const { dump(0); } +void Type::dump() const { print(dbgs()); } // Module::dump() - Allow printing of Modules from the debugger. void Module::dump() const { print(dbgs(), 0); } diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index ee257db..bf6efa1 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -74,6 +74,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "naked "; if (Attrs & Attribute::Hotpatch) Result += "hotpatch "; + if (Attrs & Attribute::NonLazyBind) + Result += "nonlazybind "; if (Attrs & Attribute::StackAlignment) { Result += "alignstack("; Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs)); diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index f8f15ca..9e93ff3 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -28,558 +28,77 @@ using namespace llvm; static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { assert(F && "Illegal to upgrade a non-existent Function."); - // Get the Function's name. - const std::string& Name = F->getName(); - - // Convenience - const FunctionType *FTy = F->getFunctionType(); - // Quickly eliminate it, if it's not a candidate. - if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || - Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') + StringRef Name = F->getName(); + if (Name.size() <= 8 || !Name.startswith("llvm.")) return false; + Name = Name.substr(5); // Strip off "llvm." + const FunctionType *FTy = F->getFunctionType(); Module *M = F->getParent(); - switch (Name[5]) { + + switch (Name[0]) { default: break; - case 'a': - // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss, - // and atomics with default address spaces to their new names to their new - // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32) - if (Name.compare(5,7,"atomic.",7) == 0) { - if (Name.compare(12,3,"lcs",3) == 0) { - std::string::size_type delim = Name.find('.',12); - F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) + - ".p0" + Name.substr(delim+1)); - NewFn = F; - return true; - } - else if (Name.compare(12,3,"las",3) == 0) { - std::string::size_type delim = Name.find('.',12); - F->setName("llvm.atomic.load.add"+Name.substr(delim) - + ".p0" + Name.substr(delim+1)); - NewFn = F; - return true; - } - else if (Name.compare(12,3,"lss",3) == 0) { - std::string::size_type delim = Name.find('.',12); - F->setName("llvm.atomic.load.sub"+Name.substr(delim) - + ".p0" + Name.substr(delim+1)); - NewFn = F; - return true; - } - else if (Name.rfind(".p") == std::string::npos) { - // We don't have an address space qualifier so this has be upgraded - // to the new name. Copy the type name at the end of the intrinsic - // and add to it - std::string::size_type delim = Name.find_last_of('.'); - assert(delim != std::string::npos && "can not find type"); - F->setName(Name + ".p0" + Name.substr(delim+1)); - NewFn = F; - return true; - } - } else if (Name.compare(5, 9, "arm.neon.", 9) == 0) { - if (((Name.compare(14, 5, "vmovl", 5) == 0 || - Name.compare(14, 5, "vaddl", 5) == 0 || - Name.compare(14, 5, "vsubl", 5) == 0 || - Name.compare(14, 5, "vaddw", 5) == 0 || - Name.compare(14, 5, "vsubw", 5) == 0 || - Name.compare(14, 5, "vmlal", 5) == 0 || - Name.compare(14, 5, "vmlsl", 5) == 0 || - Name.compare(14, 5, "vabdl", 5) == 0 || - Name.compare(14, 5, "vabal", 5) == 0) && - (Name.compare(19, 2, "s.", 2) == 0 || - Name.compare(19, 2, "u.", 2) == 0)) || - - (Name.compare(14, 4, "vaba", 4) == 0 && - (Name.compare(18, 2, "s.", 2) == 0 || - Name.compare(18, 2, "u.", 2) == 0)) || - - (Name.compare(14, 6, "vmovn.", 6) == 0)) { - - // Calls to these are transformed into IR without intrinsics. - NewFn = 0; - return true; - } - // Old versions of NEON ld/st intrinsics are missing alignment arguments. - bool isVLd = (Name.compare(14, 3, "vld", 3) == 0); - bool isVSt = (Name.compare(14, 3, "vst", 3) == 0); - if (isVLd || isVSt) { - unsigned NumVecs = Name.at(17) - '0'; - if (NumVecs == 0 || NumVecs > 4) - return false; - bool isLaneOp = (Name.compare(18, 5, "lane.", 5) == 0); - if (!isLaneOp && Name.at(18) != '.') - return false; - unsigned ExpectedArgs = 2; // for the address and alignment - if (isVSt || isLaneOp) - ExpectedArgs += NumVecs; - if (isLaneOp) - ExpectedArgs += 1; // for the lane number - unsigned NumP = FTy->getNumParams(); - if (NumP != ExpectedArgs - 1) - return false; - - // Change the name of the old (bad) intrinsic, because - // its type is incorrect, but we cannot overload that name. - F->setName(""); - - // One argument is missing: add the alignment argument. - std::vector<const Type*> NewParams; - for (unsigned p = 0; p < NumP; ++p) - NewParams.push_back(FTy->getParamType(p)); - NewParams.push_back(Type::getInt32Ty(F->getContext())); - FunctionType *NewFTy = FunctionType::get(FTy->getReturnType(), - NewParams, false); - NewFn = cast<Function>(M->getOrInsertFunction(Name, NewFTy)); - return true; - } - } - break; - case 'b': - // This upgrades the name of the llvm.bswap intrinsic function to only use - // a single type name for overloading. We only care about the old format - // 'llvm.bswap.i*.i*', so check for 'bswap.' and then for there being - // a '.' after 'bswap.' - if (Name.compare(5,6,"bswap.",6) == 0) { - std::string::size_type delim = Name.find('.',11); - - if (delim != std::string::npos) { - // Construct the new name as 'llvm.bswap' + '.i*' - F->setName(Name.substr(0,10)+Name.substr(delim)); - NewFn = F; - return true; - } - } - break; + case 'p': + // This upgrades the llvm.prefetch intrinsic to accept one more parameter, + // which is a instruction / data cache identifier. The old version only + // implicitly accepted the data version. + if (Name == "prefetch") { + // Don't do anything if it has the correct number of arguments already + if (FTy->getNumParams() == 4) + break; - case 'c': - // We only want to fix the 'llvm.ct*' intrinsics which do not have the - // correct return type, so we check for the name, and then check if the - // return type does not match the parameter type. - if ( (Name.compare(5,5,"ctpop",5) == 0 || - Name.compare(5,4,"ctlz",4) == 0 || - Name.compare(5,4,"cttz",4) == 0) && - FTy->getReturnType() != FTy->getParamType(0)) { - // We first need to change the name of the old (bad) intrinsic, because - // its type is incorrect, but we cannot overload that name. We - // arbitrarily unique it here allowing us to construct a correctly named + assert(FTy->getNumParams() == 3 && "old prefetch takes 3 args!"); + // We first need to change the name of the old (bad) intrinsic, because + // its type is incorrect, but we cannot overload that name. We + // arbitrarily unique it here allowing us to construct a correctly named // and typed function below. + std::string NameTmp = F->getName(); F->setName(""); - - // Now construct the new intrinsic with the correct name and type. We - // leave the old function around in order to query its type, whatever it - // may be, and correctly convert up to the new type. - NewFn = cast<Function>(M->getOrInsertFunction(Name, + NewFn = cast<Function>(M->getOrInsertFunction(NameTmp, + FTy->getReturnType(), FTy->getParamType(0), - FTy->getParamType(0), - (Type *)0)); + FTy->getParamType(1), + FTy->getParamType(2), + FTy->getParamType(2), + (Type*)0)); return true; } - 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 'm': { - // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the - // new format that allows overloading the pointer for different address - // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16) - const char* NewFnName = NULL; - if (Name.compare(5,8,"memcpy.i",8) == 0) { - if (Name[13] == '8') - NewFnName = "llvm.memcpy.p0i8.p0i8.i8"; - else if (Name.compare(13,2,"16") == 0) - NewFnName = "llvm.memcpy.p0i8.p0i8.i16"; - else if (Name.compare(13,2,"32") == 0) - NewFnName = "llvm.memcpy.p0i8.p0i8.i32"; - else if (Name.compare(13,2,"64") == 0) - NewFnName = "llvm.memcpy.p0i8.p0i8.i64"; - } else if (Name.compare(5,9,"memmove.i",9) == 0) { - if (Name[14] == '8') - NewFnName = "llvm.memmove.p0i8.p0i8.i8"; - else if (Name.compare(14,2,"16") == 0) - NewFnName = "llvm.memmove.p0i8.p0i8.i16"; - else if (Name.compare(14,2,"32") == 0) - NewFnName = "llvm.memmove.p0i8.p0i8.i32"; - else if (Name.compare(14,2,"64") == 0) - NewFnName = "llvm.memmove.p0i8.p0i8.i64"; - } - else if (Name.compare(5,8,"memset.i",8) == 0) { - if (Name[13] == '8') - NewFnName = "llvm.memset.p0i8.i8"; - else if (Name.compare(13,2,"16") == 0) - NewFnName = "llvm.memset.p0i8.i16"; - else if (Name.compare(13,2,"32") == 0) - NewFnName = "llvm.memset.p0i8.i32"; - else if (Name.compare(13,2,"64") == 0) - NewFnName = "llvm.memset.p0i8.i64"; - } + case 'x': { + const char *NewFnName = NULL; + // This fixes the poorly named crc32 intrinsics. + if (Name == "x86.sse42.crc32.8") + NewFnName = "llvm.x86.sse42.crc32.32.8"; + else if (Name == "x86.sse42.crc32.16") + NewFnName = "llvm.x86.sse42.crc32.32.16"; + else if (Name == "x86.sse42.crc32.32") + NewFnName = "llvm.x86.sse42.crc32.32.32"; + else if (Name == "x86.sse42.crc64.8") + NewFnName = "llvm.x86.sse42.crc32.64.8"; + else if (Name == "x86.sse42.crc64.64") + NewFnName = "llvm.x86.sse42.crc32.64.64"; + if (NewFnName) { - NewFn = cast<Function>(M->getOrInsertFunction(NewFnName, - FTy->getReturnType(), - FTy->getParamType(0), - FTy->getParamType(1), - FTy->getParamType(2), - FTy->getParamType(3), - Type::getInt1Ty(F->getContext()), - (Type *)0)); + F->setName(NewFnName); + NewFn = F; 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 - // 'llvm.part.select.i*.i*', and solve as above with bswap. - if (Name.compare(5,12,"part.select.",12) == 0) { - std::string::size_type delim = Name.find('.',17); - - if (delim != std::string::npos) { - // Construct a new name as 'llvm.part.select' + '.i*' - F->setName(Name.substr(0,16)+Name.substr(delim)); - NewFn = F; - return true; - } - break; - } - // This upgrades the llvm.part.set intrinsics similarly as above, however - // we care about 'llvm.part.set.i*.i*.i*', but only the first two types - // must match. There is an additional type specifier after these two - // matching types that we must retain when upgrading. Thus, we require - // finding 2 periods, not just one, after the intrinsic name. - if (Name.compare(5,9,"part.set.",9) == 0) { - std::string::size_type delim = Name.find('.',14); - - if (delim != std::string::npos && - Name.find('.',delim+1) != std::string::npos) { - // Construct a new name as 'llvm.part.select' + '.i*.i*' - F->setName(Name.substr(0,13)+Name.substr(delim)); - NewFn = F; - return true; - } - break; - } - - break; - case 'x': - // This fixes the poorly named crc32 intrinsics - if (Name.compare(5, 13, "x86.sse42.crc", 13) == 0) { - const char* NewFnName = NULL; - if (Name.compare(18, 2, "32", 2) == 0) { - if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) { - NewFnName = "llvm.x86.sse42.crc32.32.8"; - } else if (Name.compare(20, 3, ".16") == 0 && Name.length() == 23) { - NewFnName = "llvm.x86.sse42.crc32.32.16"; - } else if (Name.compare(20, 3, ".32") == 0 && Name.length() == 23) { - NewFnName = "llvm.x86.sse42.crc32.32.32"; - } - } - else if (Name.compare(18, 2, "64", 2) == 0) { - if (Name.compare(20, 2, ".8") == 0 && Name.length() == 22) { - NewFnName = "llvm.x86.sse42.crc32.64.8"; - } else if (Name.compare(20, 3, ".64") == 0 && Name.length() == 23) { - NewFnName = "llvm.x86.sse42.crc32.64.64"; - } - } - if (NewFnName) { - F->setName(NewFnName); - NewFn = F; - return true; - } - } - - // This fixes all MMX shift intrinsic instructions to take a - // x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8. - if (Name.compare(5, 8, "x86.mmx.", 8) == 0) { - const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext()); - - if (Name.compare(13, 4, "padd", 4) == 0 || - Name.compare(13, 4, "psub", 4) == 0 || - Name.compare(13, 4, "pmul", 4) == 0 || - Name.compare(13, 5, "pmadd", 5) == 0 || - Name.compare(13, 4, "pand", 4) == 0 || - Name.compare(13, 3, "por", 3) == 0 || - Name.compare(13, 4, "pxor", 4) == 0 || - Name.compare(13, 4, "pavg", 4) == 0 || - Name.compare(13, 4, "pmax", 4) == 0 || - Name.compare(13, 4, "pmin", 4) == 0 || - Name.compare(13, 4, "psad", 4) == 0 || - Name.compare(13, 4, "psll", 4) == 0 || - Name.compare(13, 4, "psrl", 4) == 0 || - Name.compare(13, 4, "psra", 4) == 0 || - Name.compare(13, 4, "pack", 4) == 0 || - Name.compare(13, 6, "punpck", 6) == 0 || - Name.compare(13, 4, "pcmp", 4) == 0) { - assert(FTy->getNumParams() == 2 && "MMX intrinsic takes 2 args!"); - const Type *SecondParamTy = X86_MMXTy; - - if (Name.compare(13, 5, "pslli", 5) == 0 || - Name.compare(13, 5, "psrli", 5) == 0 || - Name.compare(13, 5, "psrai", 5) == 0) - SecondParamTy = FTy->getParamType(1); - - // Don't do anything if it has the correct types. - if (FTy->getReturnType() == X86_MMXTy && - FTy->getParamType(0) == X86_MMXTy && - FTy->getParamType(1) == SecondParamTy) - break; - - // We first need to change the name of the old (bad) intrinsic, because - // its type is incorrect, but we cannot overload that name. We - // arbitrarily unique it here allowing us to construct a correctly named - // and typed function below. - F->setName(""); - - // Now construct the new intrinsic with the correct name and type. We - // leave the old function around in order to query its type, whatever it - // may be, and correctly convert up to the new type. - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, X86_MMXTy, - SecondParamTy, (Type*)0)); - return true; - } - - if (Name.compare(13, 8, "maskmovq", 8) == 0) { - // Don't do anything if it has the correct types. - if (FTy->getParamType(0) == X86_MMXTy && - FTy->getParamType(1) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - X86_MMXTy, - X86_MMXTy, - FTy->getParamType(2), - (Type*)0)); - return true; - } - - if (Name.compare(13, 8, "pmovmskb", 8) == 0) { - if (FTy->getParamType(0) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - X86_MMXTy, - (Type*)0)); - return true; - } - - if (Name.compare(13, 5, "movnt", 5) == 0) { - if (FTy->getParamType(1) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - FTy->getParamType(0), - X86_MMXTy, - (Type*)0)); - return true; - } - - if (Name.compare(13, 7, "palignr", 7) == 0) { - if (FTy->getReturnType() == X86_MMXTy && - FTy->getParamType(0) == X86_MMXTy && - FTy->getParamType(1) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - X86_MMXTy, - X86_MMXTy, - FTy->getParamType(2), - (Type*)0)); - return true; - } - - if (Name.compare(13, 5, "pextr", 5) == 0) { - if (FTy->getParamType(0) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - X86_MMXTy, - FTy->getParamType(1), - (Type*)0)); - return true; - } - - if (Name.compare(13, 5, "pinsr", 5) == 0) { - if (FTy->getReturnType() == X86_MMXTy && - FTy->getParamType(0) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - X86_MMXTy, - FTy->getParamType(1), - FTy->getParamType(2), - (Type*)0)); - return true; - } - - if (Name.compare(13, 12, "cvtsi32.si64", 12) == 0) { - if (FTy->getReturnType() == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - FTy->getParamType(0), - (Type*)0)); - return true; - } - - if (Name.compare(13, 12, "cvtsi64.si32", 12) == 0) { - if (FTy->getParamType(0) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - FTy->getReturnType(), - X86_MMXTy, - (Type*)0)); - return true; - } - - if (Name.compare(13, 8, "vec.init", 8) == 0) { - if (FTy->getReturnType() == X86_MMXTy) - break; - - F->setName(""); - - if (Name.compare(21, 2, ".b", 2) == 0) - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - FTy->getParamType(0), - FTy->getParamType(1), - FTy->getParamType(2), - FTy->getParamType(3), - FTy->getParamType(4), - FTy->getParamType(5), - FTy->getParamType(6), - FTy->getParamType(7), - (Type*)0)); - else if (Name.compare(21, 2, ".w", 2) == 0) - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - FTy->getParamType(0), - FTy->getParamType(1), - FTy->getParamType(2), - FTy->getParamType(3), - (Type*)0)); - else if (Name.compare(21, 2, ".d", 2) == 0) - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - FTy->getParamType(0), - FTy->getParamType(1), - (Type*)0)); - return true; - } - - - if (Name.compare(13, 9, "vec.ext.d", 9) == 0) { - if (FTy->getReturnType() == X86_MMXTy && - FTy->getParamType(0) == X86_MMXTy) - break; - - F->setName(""); - NewFn = cast<Function>(M->getOrInsertFunction(Name, - X86_MMXTy, - X86_MMXTy, - FTy->getParamType(1), - (Type*)0)); - return true; - } - - if (Name.compare(13, 9, "emms", 4) == 0 || - Name.compare(13, 9, "femms", 5) == 0) { - NewFn = 0; - break; - } - - // We really shouldn't get here ever. - assert(0 && "Invalid MMX intrinsic!"); - break; - } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 || - Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 || - Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 || - Name.compare(5,15,"x86.sse2.movs.d",15) == 0 || - Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 || - Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 || - Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 || - Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 || - Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) { - // Calls to these intrinsics are transformed into ShuffleVector's. - NewFn = 0; - return true; - } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) { - // Calls to these intrinsics are transformed into vector multiplies. - NewFn = 0; + // Calls to these instructions are transformed into unaligned loads. + if (Name == "x86.sse.loadu.ps" || Name == "x86.sse2.loadu.dq" || + Name == "x86.sse2.loadu.pd") return true; - } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 || - Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) { - // Calls to these intrinsics are transformed into vector shuffles, shifts, - // or 0. - NewFn = 0; - return true; - } else if (Name.compare(5, 16, "x86.sse.loadu.ps", 16) == 0 || - Name.compare(5, 17, "x86.sse2.loadu.dq", 17) == 0 || - Name.compare(5, 17, "x86.sse2.loadu.pd", 17) == 0) { - // Calls to these instructions are transformed into unaligned loads. - NewFn = 0; - return true; - } else if (Name.compare(5, 16, "x86.sse.movnt.ps", 16) == 0 || - Name.compare(5, 17, "x86.sse2.movnt.dq", 17) == 0 || - Name.compare(5, 17, "x86.sse2.movnt.pd", 17) == 0 || - Name.compare(5, 17, "x86.sse2.movnt.i", 16) == 0) { - // Calls to these instructions are transformed into nontemporal stores. - NewFn = 0; - return true; - } else if (Name.compare(5, 17, "x86.ssse3.pshuf.w", 17) == 0) { - // This is an SSE/MMX instruction. - const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext()); - NewFn = - cast<Function>(M->getOrInsertFunction("llvm.x86.sse.pshuf.w", - X86_MMXTy, - X86_MMXTy, - Type::getInt8Ty(F->getContext()), - (Type*)0)); + + // Calls to these instructions are transformed into nontemporal stores. + if (Name == "x86.sse.movnt.ps" || Name == "x86.sse2.movnt.dq" || + Name == "x86.sse2.movnt.pd" || Name == "x86.sse2.movnt.i") return true; - } break; } + } // This may not belong here. This function is effectively being overloaded // to both detect an intrinsic which needs upgrading, and to provide the @@ -601,105 +120,10 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { } bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { - StringRef Name(GV->getName()); - - // We are only upgrading one symbol here. - if (Name == ".llvm.eh.catch.all.value") { - GV->setName("llvm.eh.catch.all.value"); - return true; - } - + // Nothing to do yet. return false; } -/// ExtendNEONArgs - For NEON "long" and "wide" operations, where the results -/// have vector elements twice as big as one or both source operands, do the -/// sign- or zero-extension that used to be handled by intrinsics. The -/// extended values are returned via V0 and V1. -static void ExtendNEONArgs(CallInst *CI, Value *Arg0, Value *Arg1, - Value *&V0, Value *&V1) { - Function *F = CI->getCalledFunction(); - const std::string& Name = F->getName(); - bool isLong = (Name.at(18) == 'l'); - bool isSigned = (Name.at(19) == 's'); - - if (isSigned) { - if (isLong) - V0 = new SExtInst(Arg0, CI->getType(), "", CI); - else - V0 = Arg0; - V1 = new SExtInst(Arg1, CI->getType(), "", CI); - } else { - if (isLong) - V0 = new ZExtInst(Arg0, CI->getType(), "", CI); - else - V0 = Arg0; - V1 = new ZExtInst(Arg1, CI->getType(), "", CI); - } -} - -/// CallVABD - As part of expanding a call to one of the old NEON vabdl, vaba, -/// or vabal intrinsics, construct a call to a vabd intrinsic. Examine the -/// name of the old intrinsic to determine whether to use a signed or unsigned -/// vabd intrinsic. Get the type from the old call instruction, adjusted for -/// half-size vector elements if the old intrinsic was vabdl or vabal. -static Instruction *CallVABD(CallInst *CI, Value *Arg0, Value *Arg1) { - Function *F = CI->getCalledFunction(); - const std::string& Name = F->getName(); - bool isLong = (Name.at(18) == 'l'); - bool isSigned = (Name.at(isLong ? 19 : 18) == 's'); - - Intrinsic::ID intID; - if (isSigned) - intID = Intrinsic::arm_neon_vabds; - else - intID = Intrinsic::arm_neon_vabdu; - - const Type *Ty = CI->getType(); - if (isLong) - Ty = VectorType::getTruncatedElementVectorType(cast<const VectorType>(Ty)); - - Function *VABD = Intrinsic::getDeclaration(F->getParent(), intID, &Ty, 1); - Value *Operands[2]; - Operands[0] = Arg0; - Operands[1] = Arg1; - return CallInst::Create(VABD, Operands, Operands+2, - "upgraded."+CI->getName(), CI); -} - -/// ConstructNewCallInst - Construct a new CallInst with the signature of NewFn. -static void ConstructNewCallInst(Function *NewFn, CallInst *OldCI, - Value **Operands, unsigned NumOps, - bool AssignName = true) { - // Construct a new CallInst. - CallInst *NewCI = - CallInst::Create(NewFn, Operands, Operands + NumOps, - AssignName ? "upgraded." + OldCI->getName() : "", OldCI); - - NewCI->setTailCall(OldCI->isTailCall()); - NewCI->setCallingConv(OldCI->getCallingConv()); - - // Handle any uses of the old CallInst. If the type has changed, add a cast. - if (!OldCI->use_empty()) { - if (OldCI->getType() != NewCI->getType()) { - Function *OldFn = OldCI->getCalledFunction(); - CastInst *RetCast = - CastInst::Create(CastInst::getCastOpcode(NewCI, true, - OldFn->getReturnType(), true), - NewCI, OldFn->getReturnType(), NewCI->getName(),OldCI); - - // Replace all uses of the old call with the new cast which has the - // correct type. - OldCI->replaceAllUsesWith(RetCast); - } else { - OldCI->replaceAllUsesWith(NewCI); - } - } - - // Clean up the old call now that it has been completely upgraded. - OldCI->eraseFromParent(); -} - // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the // upgraded intrinsic. All argument and return casting must be provided in // order to seamlessly integrate with existing context. @@ -711,284 +135,9 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { assert(F && "CallInst has no function associated with it."); if (!NewFn) { - // Get the Function's name. - const std::string& Name = F->getName(); - - // Upgrade ARM NEON intrinsics. - if (Name.compare(5, 9, "arm.neon.", 9) == 0) { - Instruction *NewI; - Value *V0, *V1; - if (Name.compare(14, 7, "vmovls.", 7) == 0) { - NewI = new SExtInst(CI->getArgOperand(0), CI->getType(), - "upgraded." + CI->getName(), CI); - } else if (Name.compare(14, 7, "vmovlu.", 7) == 0) { - NewI = new ZExtInst(CI->getArgOperand(0), CI->getType(), - "upgraded." + CI->getName(), CI); - } else if (Name.compare(14, 4, "vadd", 4) == 0) { - ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); - NewI = BinaryOperator::CreateAdd(V0, V1, "upgraded."+CI->getName(), CI); - } else if (Name.compare(14, 4, "vsub", 4) == 0) { - ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); - NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI); - } else if (Name.compare(14, 4, "vmul", 4) == 0) { - ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); - NewI = BinaryOperator::CreateMul(V0, V1,"upgraded."+CI->getName(),CI); - } else if (Name.compare(14, 4, "vmla", 4) == 0) { - ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); - Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); - NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), MulI, - "upgraded."+CI->getName(), CI); - } else if (Name.compare(14, 4, "vmls", 4) == 0) { - ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); - Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); - NewI = BinaryOperator::CreateSub(CI->getArgOperand(0), MulI, - "upgraded."+CI->getName(), CI); - } else if (Name.compare(14, 4, "vabd", 4) == 0) { - NewI = CallVABD(CI, CI->getArgOperand(0), CI->getArgOperand(1)); - NewI = new ZExtInst(NewI, CI->getType(), "upgraded."+CI->getName(), CI); - } else if (Name.compare(14, 4, "vaba", 4) == 0) { - NewI = CallVABD(CI, CI->getArgOperand(1), CI->getArgOperand(2)); - if (Name.at(18) == 'l') - NewI = new ZExtInst(NewI, CI->getType(), "", CI); - NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), NewI, - "upgraded."+CI->getName(), CI); - } else if (Name.compare(14, 6, "vmovn.", 6) == 0) { - NewI = new TruncInst(CI->getArgOperand(0), CI->getType(), - "upgraded." + CI->getName(), CI); - } else { - llvm_unreachable("Unknown arm.neon function for CallInst upgrade."); - } - // Replace any uses of the old CallInst. - if (!CI->use_empty()) - CI->replaceAllUsesWith(NewI); - CI->eraseFromParent(); - return; - } - - bool isLoadH = false, isLoadL = false, isMovL = false; - bool isMovSD = false, isShufPD = false; - bool isUnpckhPD = false, isUnpcklPD = false; - bool isPunpckhQPD = false, isPunpcklQPD = false; - if (F->getName() == "llvm.x86.sse2.loadh.pd") - isLoadH = true; - else if (F->getName() == "llvm.x86.sse2.loadl.pd") - isLoadL = true; - else if (F->getName() == "llvm.x86.sse2.movl.dq") - isMovL = true; - else if (F->getName() == "llvm.x86.sse2.movs.d") - isMovSD = true; - else if (F->getName() == "llvm.x86.sse2.shuf.pd") - isShufPD = true; - else if (F->getName() == "llvm.x86.sse2.unpckh.pd") - isUnpckhPD = true; - else if (F->getName() == "llvm.x86.sse2.unpckl.pd") - isUnpcklPD = true; - else if (F->getName() == "llvm.x86.sse2.punpckh.qdq") - isPunpckhQPD = true; - else if (F->getName() == "llvm.x86.sse2.punpckl.qdq") - isPunpcklQPD = true; - - if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD || - isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { - std::vector<Constant*> Idxs; - Value *Op0 = CI->getArgOperand(0); - ShuffleVectorInst *SI = NULL; - if (isLoadH || isLoadL) { - Value *Op1 = UndefValue::get(Op0->getType()); - Value *Addr = new BitCastInst(CI->getArgOperand(1), - Type::getDoublePtrTy(C), - "upgraded.", CI); - Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI); - Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0); - Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI); - - if (isLoadH) { - 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::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::getInt32Ty(C), 0); - Idxs.push_back(Zero); - Idxs.push_back(Zero); - Idxs.push_back(Zero); - Idxs.push_back(Zero); - Value *ZeroV = ConstantVector::get(Idxs); - - Idxs.clear(); - 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->getArgOperand(1); - if (isMovSD) { - 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::getInt32Ty(C), 1)); - Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); - } else { - 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->getArgOperand(1); - unsigned MaskVal = - cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); - 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); - } - - assert(SI && "Unexpected!"); - - // Handle any uses of the old CallInst. - if (!CI->use_empty()) - // Replace all uses of the old call with the new cast which has the - // correct type. - CI->replaceAllUsesWith(SI); - - // Clean up the old call now that it has been completely upgraded. - CI->eraseFromParent(); - } else if (F->getName() == "llvm.x86.sse41.pmulld") { - // Upgrade this set of intrinsics into vector multiplies. - Instruction *Mul = BinaryOperator::CreateMul(CI->getArgOperand(0), - CI->getArgOperand(1), - CI->getName(), - CI); - // Fix up all the uses with our new multiply. - if (!CI->use_empty()) - CI->replaceAllUsesWith(Mul); - - // Remove upgraded multiply. - CI->eraseFromParent(); - } else if (F->getName() == "llvm.x86.ssse3.palign.r") { - Value *Op1 = CI->getArgOperand(0); - Value *Op2 = CI->getArgOperand(1); - Value *Op3 = CI->getArgOperand(2); - unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); - Value *Rep; - IRBuilder<> Builder(C); - Builder.SetInsertPoint(CI->getParent(), CI); - - // If palignr is shifting the pair of input vectors less than 9 bytes, - // emit a shuffle instruction. - if (shiftVal <= 8) { - const Type *IntTy = Type::getInt32Ty(C); - const Type *EltTy = Type::getInt8Ty(C); - const Type *VecTy = VectorType::get(EltTy, 8); - - Op2 = Builder.CreateBitCast(Op2, VecTy); - Op1 = Builder.CreateBitCast(Op1, VecTy); - - llvm::SmallVector<llvm::Constant*, 8> Indices; - for (unsigned i = 0; i != 8; ++i) - Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); - - Value *SV = ConstantVector::get(Indices); - Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); - Rep = Builder.CreateBitCast(Rep, F->getReturnType()); - } - - // If palignr is shifting the pair of input vectors more than 8 but less - // than 16 bytes, emit a logical right shift of the destination. - else if (shiftVal < 16) { - // MMX has these as 1 x i64 vectors for some odd optimization reasons. - const Type *EltTy = Type::getInt64Ty(C); - const Type *VecTy = VectorType::get(EltTy, 1); - - Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); - Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8); - - // create i32 constant - Function *I = - Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q); - Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); - } - - // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. - else { - Rep = Constant::getNullValue(F->getReturnType()); - } - - // Replace any uses with our new instruction. - if (!CI->use_empty()) - CI->replaceAllUsesWith(Rep); - - // Remove upgraded instruction. - CI->eraseFromParent(); - - } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") { - Value *Op1 = CI->getArgOperand(0); - Value *Op2 = CI->getArgOperand(1); - Value *Op3 = CI->getArgOperand(2); - unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); - Value *Rep; - IRBuilder<> Builder(C); - Builder.SetInsertPoint(CI->getParent(), CI); - - // If palignr is shifting the pair of input vectors less than 17 bytes, - // emit a shuffle instruction. - if (shiftVal <= 16) { - const Type *IntTy = Type::getInt32Ty(C); - const Type *EltTy = Type::getInt8Ty(C); - const Type *VecTy = VectorType::get(EltTy, 16); - - Op2 = Builder.CreateBitCast(Op2, VecTy); - Op1 = Builder.CreateBitCast(Op1, VecTy); - - llvm::SmallVector<llvm::Constant*, 16> Indices; - for (unsigned i = 0; i != 16; ++i) - Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); - - Value *SV = ConstantVector::get(Indices); - Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); - Rep = Builder.CreateBitCast(Rep, F->getReturnType()); - } - - // If palignr is shifting the pair of input vectors more than 16 but less - // than 32 bytes, emit a logical right shift of the destination. - else if (shiftVal < 32) { - const Type *EltTy = Type::getInt64Ty(C); - const Type *VecTy = VectorType::get(EltTy, 2); - const Type *IntTy = Type::getInt32Ty(C); - - Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); - Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8); - - // create i32 constant - Function *I = - Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq); - Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); - } - - // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. - else { - Rep = Constant::getNullValue(F->getReturnType()); - } - - // Replace any uses with our new instruction. - if (!CI->use_empty()) - CI->replaceAllUsesWith(Rep); - - // Remove upgraded instruction. - CI->eraseFromParent(); - - } else if (F->getName() == "llvm.x86.sse.loadu.ps" || - F->getName() == "llvm.x86.sse2.loadu.dq" || - F->getName() == "llvm.x86.sse2.loadu.pd") { + if (F->getName() == "llvm.x86.sse.loadu.ps" || + F->getName() == "llvm.x86.sse2.loadu.dq" || + F->getName() == "llvm.x86.sse2.loadu.pd") { // Convert to a native, unaligned load. const Type *VecTy = CI->getType(); const Type *IntTy = IntegerType::get(C, 128); @@ -1040,306 +189,25 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { } switch (NewFn->getIntrinsicID()) { - default: llvm_unreachable("Unknown function for CallInst upgrade."); - case Intrinsic::arm_neon_vld1: - case Intrinsic::arm_neon_vld2: - case Intrinsic::arm_neon_vld3: - case Intrinsic::arm_neon_vld4: - case Intrinsic::arm_neon_vst1: - case Intrinsic::arm_neon_vst2: - case Intrinsic::arm_neon_vst3: - case Intrinsic::arm_neon_vst4: - case Intrinsic::arm_neon_vld2lane: - case Intrinsic::arm_neon_vld3lane: - case Intrinsic::arm_neon_vld4lane: - case Intrinsic::arm_neon_vst2lane: - case Intrinsic::arm_neon_vst3lane: - case Intrinsic::arm_neon_vst4lane: { - // Add a default alignment argument of 1. - SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); - Operands.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); - CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), - CI->getName(), CI); - NewCI->setTailCall(CI->isTailCall()); - NewCI->setCallingConv(CI->getCallingConv()); - - // Handle any uses of the old CallInst. - if (!CI->use_empty()) - // Replace all uses of the old call with the new cast which has the - // correct type. - CI->replaceAllUsesWith(NewCI); - - // Clean up the old call now that it has been completely upgraded. - CI->eraseFromParent(); - break; - } - - case Intrinsic::x86_mmx_padd_b: - case Intrinsic::x86_mmx_padd_w: - case Intrinsic::x86_mmx_padd_d: - case Intrinsic::x86_mmx_padd_q: - case Intrinsic::x86_mmx_padds_b: - case Intrinsic::x86_mmx_padds_w: - case Intrinsic::x86_mmx_paddus_b: - case Intrinsic::x86_mmx_paddus_w: - case Intrinsic::x86_mmx_psub_b: - case Intrinsic::x86_mmx_psub_w: - case Intrinsic::x86_mmx_psub_d: - case Intrinsic::x86_mmx_psub_q: - case Intrinsic::x86_mmx_psubs_b: - case Intrinsic::x86_mmx_psubs_w: - case Intrinsic::x86_mmx_psubus_b: - case Intrinsic::x86_mmx_psubus_w: - case Intrinsic::x86_mmx_pmulh_w: - case Intrinsic::x86_mmx_pmull_w: - case Intrinsic::x86_mmx_pmulhu_w: - case Intrinsic::x86_mmx_pmulu_dq: - case Intrinsic::x86_mmx_pmadd_wd: - case Intrinsic::x86_mmx_pand: - case Intrinsic::x86_mmx_pandn: - case Intrinsic::x86_mmx_por: - case Intrinsic::x86_mmx_pxor: - case Intrinsic::x86_mmx_pavg_b: - case Intrinsic::x86_mmx_pavg_w: - case Intrinsic::x86_mmx_pmaxu_b: - case Intrinsic::x86_mmx_pmaxs_w: - case Intrinsic::x86_mmx_pminu_b: - case Intrinsic::x86_mmx_pmins_w: - case Intrinsic::x86_mmx_psad_bw: - case Intrinsic::x86_mmx_psll_w: - case Intrinsic::x86_mmx_psll_d: - case Intrinsic::x86_mmx_psll_q: - case Intrinsic::x86_mmx_pslli_w: - case Intrinsic::x86_mmx_pslli_d: - case Intrinsic::x86_mmx_pslli_q: - case Intrinsic::x86_mmx_psrl_w: - case Intrinsic::x86_mmx_psrl_d: - case Intrinsic::x86_mmx_psrl_q: - case Intrinsic::x86_mmx_psrli_w: - case Intrinsic::x86_mmx_psrli_d: - case Intrinsic::x86_mmx_psrli_q: - case Intrinsic::x86_mmx_psra_w: - case Intrinsic::x86_mmx_psra_d: - case Intrinsic::x86_mmx_psrai_w: - case Intrinsic::x86_mmx_psrai_d: - case Intrinsic::x86_mmx_packsswb: - case Intrinsic::x86_mmx_packssdw: - case Intrinsic::x86_mmx_packuswb: - case Intrinsic::x86_mmx_punpckhbw: - case Intrinsic::x86_mmx_punpckhwd: - case Intrinsic::x86_mmx_punpckhdq: - case Intrinsic::x86_mmx_punpcklbw: - case Intrinsic::x86_mmx_punpcklwd: - case Intrinsic::x86_mmx_punpckldq: - case Intrinsic::x86_mmx_pcmpeq_b: - case Intrinsic::x86_mmx_pcmpeq_w: - case Intrinsic::x86_mmx_pcmpeq_d: - case Intrinsic::x86_mmx_pcmpgt_b: - case Intrinsic::x86_mmx_pcmpgt_w: - case Intrinsic::x86_mmx_pcmpgt_d: { - Value *Operands[2]; - - // Cast the operand to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - - switch (NewFn->getIntrinsicID()) { - default: - // Cast to the X86 MMX type. - Operands[1] = new BitCastInst(CI->getArgOperand(1), - NewFn->getFunctionType()->getParamType(1), - "upgraded.", CI); - break; - case Intrinsic::x86_mmx_pslli_w: - case Intrinsic::x86_mmx_pslli_d: - case Intrinsic::x86_mmx_pslli_q: - case Intrinsic::x86_mmx_psrli_w: - case Intrinsic::x86_mmx_psrli_d: - case Intrinsic::x86_mmx_psrli_q: - case Intrinsic::x86_mmx_psrai_w: - case Intrinsic::x86_mmx_psrai_d: - // These take an i32 as their second parameter. - Operands[1] = CI->getArgOperand(1); - break; - } - - ConstructNewCallInst(NewFn, CI, Operands, 2); - break; - } - case Intrinsic::x86_mmx_maskmovq: { - Value *Operands[3]; - - // Cast the operands to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - Operands[1] = new BitCastInst(CI->getArgOperand(1), - NewFn->getFunctionType()->getParamType(1), - "upgraded.", CI); - Operands[2] = CI->getArgOperand(2); - - ConstructNewCallInst(NewFn, CI, Operands, 3, false); - break; - } - case Intrinsic::x86_mmx_pmovmskb: { - Value *Operands[1]; - - // Cast the operand to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - - ConstructNewCallInst(NewFn, CI, Operands, 1); - break; - } - case Intrinsic::x86_mmx_movnt_dq: { - Value *Operands[2]; - - Operands[0] = CI->getArgOperand(0); - - // Cast the operand to the X86 MMX type. - Operands[1] = new BitCastInst(CI->getArgOperand(1), - NewFn->getFunctionType()->getParamType(1), - "upgraded.", CI); - - ConstructNewCallInst(NewFn, CI, Operands, 2, false); - break; - } - case Intrinsic::x86_mmx_palignr_b: { - Value *Operands[3]; - - // Cast the operands to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - Operands[1] = new BitCastInst(CI->getArgOperand(1), - NewFn->getFunctionType()->getParamType(1), - "upgraded.", CI); - Operands[2] = CI->getArgOperand(2); - - ConstructNewCallInst(NewFn, CI, Operands, 3); - break; - } - case Intrinsic::x86_mmx_pextr_w: { - Value *Operands[2]; - - // Cast the operands to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - Operands[1] = CI->getArgOperand(1); - - ConstructNewCallInst(NewFn, CI, Operands, 2); - break; - } - case Intrinsic::x86_mmx_pinsr_w: { - Value *Operands[3]; - - // Cast the operands to the X86 MMX type. - Operands[0] = new BitCastInst(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded.", CI); - Operands[1] = CI->getArgOperand(1); - Operands[2] = CI->getArgOperand(2); - - ConstructNewCallInst(NewFn, CI, Operands, 3); - break; - } - case Intrinsic::x86_sse_pshuf_w: { + case Intrinsic::prefetch: { IRBuilder<> Builder(C); Builder.SetInsertPoint(CI->getParent(), CI); + const llvm::Type *I32Ty = llvm::Type::getInt32Ty(CI->getContext()); - // Cast the operand to the X86 MMX type. - Value *Operands[2]; - Operands[0] = - Builder.CreateBitCast(CI->getArgOperand(0), - NewFn->getFunctionType()->getParamType(0), - "upgraded."); - Operands[1] = - Builder.CreateTrunc(CI->getArgOperand(1), - Type::getInt8Ty(C), - "upgraded."); - - ConstructNewCallInst(NewFn, CI, Operands, 2); - break; - } - - case Intrinsic::ctlz: - case Intrinsic::ctpop: - case Intrinsic::cttz: { - // Build a small vector of the original arguments. - SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); - - // Construct a new CallInst - 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()) { - // Check for sign extend parameter attributes on the return values. - bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt); - bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt); - - // Construct an appropriate cast from the new return type to the old. - CastInst *RetCast = CastInst::Create( - CastInst::getCastOpcode(NewCI, SrcSExt, - F->getReturnType(), - DestSExt), - NewCI, F->getReturnType(), - NewCI->getName(), CI); - NewCI->moveBefore(RetCast); - - // Replace all uses of the old call with the new cast which has the - // correct type. - CI->replaceAllUsesWith(RetCast); - } - - // Clean up the old call now that it has been completely upgraded. - CI->eraseFromParent(); - } - break; - case Intrinsic::eh_selector: - case Intrinsic::eh_typeid_for: { - // Only the return type changed. - SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_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; - case Intrinsic::memcpy: - case Intrinsic::memmove: - case Intrinsic::memset: { - // Add isVolatile - const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext()); - Value *Operands[5] = { CI->getArgOperand(0), CI->getArgOperand(1), - CI->getArgOperand(2), CI->getArgOperand(3), - llvm::ConstantInt::get(I1Ty, 0) }; - CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5, + // Add the extra "data cache" argument + Value *Operands[4] = { CI->getArgOperand(0), CI->getArgOperand(1), + CI->getArgOperand(2), + llvm::ConstantInt::get(I32Ty, 1) }; + CallInst *NewCI = CallInst::Create(NewFn, Operands, CI->getName(), CI); NewCI->setTailCall(CI->isTailCall()); NewCI->setCallingConv(CI->getCallingConv()); // Handle any uses of the old CallInst. if (!CI->use_empty()) - // Replace all uses of the old call with the new cast which has the + // Replace all uses of the old call with the new cast which has the // correct type. CI->replaceAllUsesWith(NewCI); - + // Clean up the old call now that it has been completely upgraded. CI->eraseFromParent(); break; @@ -1354,13 +222,13 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); // Upgrade the function and check if it is a totaly new function. - Function* NewFn; + Function *NewFn; if (UpgradeIntrinsicFunction(F, NewFn)) { if (NewFn != F) { // Replace all uses to the old function with the new one if necessary. for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); UI != UE; ) { - if (CallInst* CI = dyn_cast<CallInst>(*UI++)) + if (CallInst *CI = dyn_cast<CallInst>(*UI++)) UpgradeIntrinsicCall(CI, NewFn); } // Remove old function, no longer used, from the module. @@ -1373,37 +241,27 @@ void llvm::UpgradeCallsToIntrinsic(Function* F) { /// If an llvm.dbg.declare intrinsic is invalid, then this function simply /// strips that use. void llvm::CheckDebugInfoIntrinsics(Module *M) { - - if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { - while (!FuncStart->use_empty()) { - CallInst *CI = cast<CallInst>(FuncStart->use_back()); - CI->eraseFromParent(); - } + while (!FuncStart->use_empty()) + cast<CallInst>(FuncStart->use_back())->eraseFromParent(); FuncStart->eraseFromParent(); } if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { - while (!StopPoint->use_empty()) { - CallInst *CI = cast<CallInst>(StopPoint->use_back()); - CI->eraseFromParent(); - } + while (!StopPoint->use_empty()) + cast<CallInst>(StopPoint->use_back())->eraseFromParent(); StopPoint->eraseFromParent(); } if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { - while (!RegionStart->use_empty()) { - CallInst *CI = cast<CallInst>(RegionStart->use_back()); - CI->eraseFromParent(); - } + while (!RegionStart->use_empty()) + cast<CallInst>(RegionStart->use_back())->eraseFromParent(); RegionStart->eraseFromParent(); } if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { - while (!RegionEnd->use_empty()) { - CallInst *CI = cast<CallInst>(RegionEnd->use_back()); - CI->eraseFromParent(); - } + while (!RegionEnd->use_empty()) + cast<CallInst>(RegionEnd->use_back())->eraseFromParent(); RegionEnd->eraseFromParent(); } diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 955a028..70265c8 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -147,6 +147,26 @@ Instruction* BasicBlock::getFirstNonPHIOrDbg() { return &*i; } +Instruction* BasicBlock::getFirstNonPHIOrDbgOrLifetime() { + // All valid basic blocks should have a terminator, + // which is not a PHINode. If we have an invalid basic + // block we'll get an assertion failure when dereferencing + // a past-the-end iterator. + BasicBlock::iterator i = begin(); + for (;; ++i) { + if (isa<PHINode>(i) || isa<DbgInfoIntrinsic>(i)) + continue; + + const IntrinsicInst *II = dyn_cast<IntrinsicInst>(i); + if (!II) + break; + if (II->getIntrinsicID() != Intrinsic::lifetime_start && + II->getIntrinsicID() != Intrinsic::lifetime_end) + break; + } + return &*i; +} + void BasicBlock::dropAllReferences() { for(iterator I = begin(), E = end(); I != E; ++I) I->dropAllReferences(); @@ -227,8 +247,8 @@ void BasicBlock::removePredecessor(BasicBlock *Pred, // If the PHI _HAD_ two uses, replace PHI node with its now *single* value if (max_idx == 2) { - if (PN->getOperand(0) != PN) - PN->replaceAllUsesWith(PN->getOperand(0)); + if (PN->getIncomingValue(0) != PN) + PN->replaceAllUsesWith(PN->getIncomingValue(0)); else // We are left with an infinite loop with no entries: kill the PHI. PN->replaceAllUsesWith(UndefValue::get(PN->getType())); @@ -308,3 +328,19 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) { return New; } +void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { + TerminatorInst *TI = getTerminator(); + if (!TI) + // Cope with being called on a BasicBlock that doesn't have a terminator + // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this. + return; + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { + BasicBlock *Succ = TI->getSuccessor(i); + for (iterator II = Succ->begin(); PHINode *PN = dyn_cast<PHINode>(II); + ++II) { + int i; + while ((i = PN->getBasicBlockIndex(this)) >= 0) + PN->setIncomingBlock(i, New); + } + } +} diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt index 6bde263..f60dd06 100644 --- a/lib/VMCore/CMakeLists.txt +++ b/lib/VMCore/CMakeLists.txt @@ -29,7 +29,6 @@ add_llvm_library(LLVMCore PassRegistry.cpp PrintModulePass.cpp Type.cpp - TypeSymbolTable.cpp Use.cpp User.cpp Value.cpp diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 9985ada..323e2a2 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -559,7 +559,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy)); - return ConstantVector::get(DestVecTy, res); + return ConstantVector::get(res); } // We actually have to do a cast now. Perform the cast according to the @@ -730,9 +730,12 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, } + if (isa<UndefValue>(Cond)) { + if (isa<UndefValue>(V1)) return V1; + return V2; + } if (isa<UndefValue>(V1)) return V2; if (isa<UndefValue>(V2)) return V1; - if (isa<UndefValue>(Cond)) return V1; if (V1 == V2) return V1; if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) { @@ -877,42 +880,38 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, } Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg, - const unsigned *Idxs, - unsigned NumIdx) { + ArrayRef<unsigned> Idxs) { // Base case: no indices, so return the entire value. - if (NumIdx == 0) + if (Idxs.empty()) return Agg; if (isa<UndefValue>(Agg)) // ev(undef, x) -> undef return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(), - Idxs, - Idxs + NumIdx)); + Idxs)); if (isa<ConstantAggregateZero>(Agg)) // ev(0, x) -> 0 return Constant::getNullValue(ExtractValueInst::getIndexedType(Agg->getType(), - Idxs, - Idxs + NumIdx)); + Idxs)); // Otherwise recurse. if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg)) - return ConstantFoldExtractValueInstruction(CS->getOperand(*Idxs), - Idxs+1, NumIdx-1); + return ConstantFoldExtractValueInstruction(CS->getOperand(Idxs[0]), + Idxs.slice(1)); if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg)) - return ConstantFoldExtractValueInstruction(CA->getOperand(*Idxs), - Idxs+1, NumIdx-1); + return ConstantFoldExtractValueInstruction(CA->getOperand(Idxs[0]), + Idxs.slice(1)); ConstantVector *CV = cast<ConstantVector>(Agg); - return ConstantFoldExtractValueInstruction(CV->getOperand(*Idxs), - Idxs+1, NumIdx-1); + return ConstantFoldExtractValueInstruction(CV->getOperand(Idxs[0]), + Idxs.slice(1)); } Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, - const unsigned *Idxs, - unsigned NumIdx) { + ArrayRef<unsigned> Idxs) { // Base case: no indices, so replace the entire value. - if (NumIdx == 0) + if (Idxs.empty()) return Val; if (isa<UndefValue>(Agg)) { @@ -934,15 +933,15 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); Constant *Op = - (*Idxs == i) ? + (Idxs[0] == i) ? ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy), - Val, Idxs+1, NumIdx-1) : + Val, Idxs.slice(1)) : UndefValue::get(MemberTy); Ops[i] = Op; } if (const StructType* ST = dyn_cast<StructType>(AggTy)) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } @@ -965,15 +964,15 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); Constant *Op = - (*Idxs == i) ? + (Idxs[0] == i) ? ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy), - Val, Idxs+1, NumIdx-1) : + Val, Idxs.slice(1)) : Constant::getNullValue(MemberTy); Ops[i] = Op; } if (const StructType *ST = dyn_cast<StructType>(AggTy)) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } @@ -982,13 +981,13 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, std::vector<Constant*> Ops(Agg->getNumOperands()); for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { Constant *Op = cast<Constant>(Agg->getOperand(i)); - if (*Idxs == i) - Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs+1, NumIdx-1); + if (Idxs[0] == i) + Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs.slice(1)); Ops[i] = Op; } if (const StructType* ST = dyn_cast<StructType>(Agg->getType())) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); } @@ -1014,20 +1013,38 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::Add: case Instruction::Sub: return UndefValue::get(C1->getType()); - case Instruction::Mul: case Instruction::And: + if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef & undef -> undef + return C1; + return Constant::getNullValue(C1->getType()); // undef & X -> 0 + case Instruction::Mul: { + ConstantInt *CI; + // X * undef -> undef if X is odd or undef + if (((CI = dyn_cast<ConstantInt>(C1)) && CI->getValue()[0]) || + ((CI = dyn_cast<ConstantInt>(C2)) && CI->getValue()[0]) || + (isa<UndefValue>(C1) && isa<UndefValue>(C2))) + return UndefValue::get(C1->getType()); + + // X * undef -> 0 otherwise return Constant::getNullValue(C1->getType()); + } case Instruction::UDiv: case Instruction::SDiv: + // undef / 1 -> undef + if (Opcode == Instruction::UDiv || Opcode == Instruction::SDiv) + if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) + if (CI2->isOne()) + return C1; + // FALL THROUGH case Instruction::URem: case Instruction::SRem: if (!isa<UndefValue>(C2)) // undef / X -> 0 return Constant::getNullValue(C1->getType()); return C2; // X / undef -> undef case Instruction::Or: // X | undef -> -1 - if (const VectorType *PTy = dyn_cast<VectorType>(C1->getType())) - return Constant::getAllOnesValue(PTy); - return Constant::getAllOnesValue(C1->getType()); + if (isa<UndefValue>(C1) && isa<UndefValue>(C2)) // undef | undef -> undef + return C1; + return Constant::getAllOnesValue(C1->getType()); // undef | X -> ~0 case Instruction::LShr: if (isa<UndefValue>(C2) && isa<UndefValue>(C1)) return C1; // undef lshr undef -> undef @@ -1041,6 +1058,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, else return C1; // X ashr undef --> X case Instruction::Shl: + if (isa<UndefValue>(C2) && isa<UndefValue>(C1)) + return C1; // undef shl undef -> undef // undef << X -> 0 or X << undef -> 0 return Constant::getNullValue(C1->getType()); } @@ -1443,8 +1462,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, /// isZeroSizedType - This type is zero sized if its an array or structure of /// zero sized types. The only leaf zero sized type is an empty structure. static bool isMaybeZeroSizedType(const Type *Ty) { - if (Ty->isOpaqueTy()) return true; // Can't say. if (const StructType *STy = dyn_cast<StructType>(Ty)) { + if (STy->isOpaque()) return true; // Can't say. // If all of elements have zero size, this does too. for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) @@ -1831,7 +1850,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) { // For EQ and NE, we can always pick a value for the undef to make the // predicate pass or fail, so we can return undef. - if (ICmpInst::isEquality(ICmpInst::Predicate(pred))) + // Also, if both operands are undef, we can return undef. + if (ICmpInst::isEquality(ICmpInst::Predicate(pred)) || + (isa<UndefValue>(C1) && isa<UndefValue>(C2))) return UndefValue::get(ResultTy); // Otherwise, pick the same value as the non-undef operand, and fold // it to true or false. @@ -2147,9 +2168,9 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C, bool inBounds, IndexTy const *Idxs, unsigned NumIdx) { + if (NumIdx == 0) return C; Constant *Idx0 = cast<Constant>(Idxs[0]); - if (NumIdx == 0 || - (NumIdx == 1 && Idx0->isNullValue())) + if ((NumIdx == 1 && Idx0->isNullValue())) return C; if (isa<UndefValue>(C)) { diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index 0ecd7b4..653a1c3 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -19,6 +19,8 @@ #ifndef CONSTANTFOLDING_H #define CONSTANTFOLDING_H +#include "llvm/ADT/ArrayRef.h" + namespace llvm { class Value; class Constant; @@ -38,11 +40,9 @@ namespace llvm { Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, Constant *Mask); Constant *ConstantFoldExtractValueInstruction(Constant *Agg, - const unsigned *Idxs, - unsigned NumIdx); + ArrayRef<unsigned> Idxs); Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, - const unsigned *Idxs, - unsigned NumIdx); + ArrayRef<unsigned> Idxs); Constant *ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2); Constant *ConstantFoldCompareInstruction(unsigned short predicate, diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 15d7793..316c884 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include <algorithm> #include <cstdarg> using namespace llvm; @@ -39,6 +40,28 @@ using namespace llvm; // Constant Class //===----------------------------------------------------------------------===// +bool Constant::isNegativeZeroValue() const { + // Floating point values have an explicit -0.0 value. + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) + return CFP->isZero() && CFP->isNegative(); + + // Otherwise, just use +0.0. + return isNullValue(); +} + +bool Constant::isNullValue() const { + // 0 is null. + if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) + return CI->isZero(); + + // +0.0 is null. + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) + return CFP->isZero() && !CFP->isNegative(); + + // constant zero is zero for aggregates and cpnull is null for pointers. + return isa<ConstantAggregateZero>(this) || isa<ConstantPointerNull>(this); +} + // Constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(const Type *Ty) { switch (Ty->getTypeID()) { @@ -541,11 +564,7 @@ ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) "FP type Mismatch"); } -bool ConstantFP::isNullValue() const { - return Val.isZero() && !Val.isNegative(); -} - -bool ConstantFP::isExactlyValue(const APFloat& V) const { +bool ConstantFP::isExactlyValue(const APFloat &V) const { return Val.bitwiseIsEqual(V); } @@ -571,8 +590,7 @@ ConstantArray::ConstantArray(const ArrayType *T, } } -Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector<Constant*> &V) { +Constant *ConstantArray::get(const ArrayType *Ty, ArrayRef<Constant*> V) { for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); @@ -592,13 +610,6 @@ Constant *ConstantArray::get(const ArrayType *Ty, 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. @@ -621,63 +632,64 @@ Constant *ConstantArray::get(LLVMContext &Context, StringRef Str, return get(ATy, ElementVals); } +/// getTypeForElements - Return an anonymous struct type to use for a constant +/// with the specified set of elements. The list must not be empty. +StructType *ConstantStruct::getTypeForElements(LLVMContext &Context, + ArrayRef<Constant*> V, + bool Packed) { + SmallVector<Type*, 16> EltTypes; + for (unsigned i = 0, e = V.size(); i != e; ++i) + EltTypes.push_back(V[i]->getType()); + + return StructType::get(Context, EltTypes, Packed); +} + + +StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V, + bool Packed) { + assert(!V.empty() && + "ConstantStruct::getTypeForElements cannot be called on empty list"); + return getTypeForElements(V[0]->getContext(), V, Packed); +} + + ConstantStruct::ConstantStruct(const StructType *T, const std::vector<Constant*> &V) : Constant(T, ConstantStructVal, OperandTraits<ConstantStruct>::op_end(this) - V.size(), V.size()) { - assert(V.size() == T->getNumElements() && + assert((T->isOpaque() || V.size() == T->getNumElements()) && "Invalid initializer vector for constant structure"); Use *OL = OperandList; 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()) && + assert((T->isOpaque() || 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... +Constant *ConstantStruct::get(const StructType *ST, ArrayRef<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()) - 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); -} + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, 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); + assert((ST->isOpaque() || ST->getNumElements() == V.size()) && + "Incorrect # elements specified to ConstantStruct::get"); + return ConstantAggregateZero::get(ST); } -Constant* ConstantStruct::get(LLVMContext &Context, bool Packed, - Constant * Val, ...) { +Constant* ConstantStruct::get(const StructType *T, ...) { va_list ap; - std::vector<Constant*> Values; - va_start(ap, Val); - while (Val) { + SmallVector<Constant*, 8> Values; + va_start(ap, T); + while (Constant *Val = va_arg(ap, llvm::Constant*)) Values.push_back(Val); - Val = va_arg(ap, llvm::Constant*); - } va_end(ap); - return get(Context, Values, Packed); + return get(T, Values); } ConstantVector::ConstantVector(const VectorType *T, @@ -696,9 +708,9 @@ ConstantVector::ConstantVector(const VectorType *T, } // ConstantVector accessors. -Constant *ConstantVector::get(const VectorType *T, - const std::vector<Constant*> &V) { +Constant *ConstantVector::get(ArrayRef<Constant*> V) { assert(!V.empty() && "Vectors can't be empty"); + const VectorType *T = VectorType::get(V.front()->getType(), V.size()); LLVMContextImpl *pImpl = T->getContext().pImpl; // If this is an all-undef or all-zero vector, return a @@ -723,12 +735,6 @@ Constant *ConstantVector::get(const VectorType *T, return pImpl->VectorConstants.getOrCreate(T, V); } -Constant *ConstantVector::get(ArrayRef<Constant*> V) { - // FIXME: make this the primary ctor method. - assert(!V.empty() && "Vectors cannot be empty"); - return get(VectorType::get(V.front()->getType(), V.size()), V.vec()); -} - // 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 // Constant.h @@ -779,8 +785,7 @@ ArrayRef<unsigned> ConstantExpr::getIndices() const { } unsigned ConstantExpr::getPredicate() const { - assert(getOpcode() == Instruction::FCmp || - getOpcode() == Instruction::ICmp); + assert(isCompare()); return ((const CompareConstantExpr*)this)->predicate; } @@ -851,17 +856,15 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { } /// getWithOperands - This returns the current constant expression with the -/// operands replaced with the specified values. The specified operands must -/// match count and type with the existing ones. +/// operands replaced with the specified values. The specified array must +/// have the same number of operands as our current one. Constant *ConstantExpr:: -getWithOperands(ArrayRef<Constant*> Ops) const { +getWithOperands(ArrayRef<Constant*> Ops, const Type *Ty) const { assert(Ops.size() == getNumOperands() && "Operand count mismatch!"); - bool AnyChange = false; - for (unsigned i = 0; i != Ops.size(); ++i) { - assert(Ops[i]->getType() == getOperand(i)->getType() && - "Operand type mismatch!"); + bool AnyChange = Ty != getType(); + for (unsigned i = 0; i != Ops.size(); ++i) AnyChange |= Ops[i] != getOperand(i); - } + if (!AnyChange) // No operands changed, return self. return const_cast<ConstantExpr*>(this); @@ -878,7 +881,7 @@ getWithOperands(ArrayRef<Constant*> Ops) const { case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: - return ConstantExpr::getCast(getOpcode(), Ops[0], getType()); + return ConstantExpr::getCast(getOpcode(), Ops[0], Ty); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); case Instruction::InsertElement: @@ -976,14 +979,14 @@ ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) { /// destroyConstant - Remove the constant from the constant table... /// void ConstantAggregateZero::destroyConstant() { - getRawType()->getContext().pImpl->AggZeroConstants.remove(this); + getType()->getContext().pImpl->AggZeroConstants.remove(this); destroyConstantImpl(); } /// destroyConstant - Remove the constant from the constant table... /// void ConstantArray::destroyConstant() { - getRawType()->getContext().pImpl->ArrayConstants.remove(this); + getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } @@ -1023,44 +1026,54 @@ bool ConstantArray::isCString() const { } -/// getAsString - If the sub-element type of this array is i8 -/// then this method converts the array to an std::string and returns it. -/// Otherwise, it asserts out. +/// convertToString - Helper function for getAsString() and getAsCString(). +static std::string convertToString(const User *U, unsigned len) { + std::string Result; + Result.reserve(len); + for (unsigned i = 0; i != len; ++i) + Result.push_back((char)cast<ConstantInt>(U->getOperand(i))->getZExtValue()); + return Result; +} + +/// getAsString - If this array is isString(), then this method converts the +/// array to an std::string and returns it. Otherwise, it asserts out. /// std::string ConstantArray::getAsString() const { assert(isString() && "Not a string!"); - std::string Result; - Result.reserve(getNumOperands()); - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - Result.push_back((char)cast<ConstantInt>(getOperand(i))->getZExtValue()); - return Result; + return convertToString(this, getNumOperands()); } -//---- ConstantStruct::get() implementation... -// +/// getAsCString - If this array is isCString(), then this method converts the +/// array (without the trailing null byte) to an std::string and returns it. +/// Otherwise, it asserts out. +/// +std::string ConstantArray::getAsCString() const { + assert(isCString() && "Not a string!"); + return convertToString(this, getNumOperands() - 1); +} -namespace llvm { -} +//---- ConstantStruct::get() implementation... +// // destroyConstant - Remove the constant from the constant table... // void ConstantStruct::destroyConstant() { - getRawType()->getContext().pImpl->StructConstants.remove(this); + getType()->getContext().pImpl->StructConstants.remove(this); destroyConstantImpl(); } // destroyConstant - Remove the constant from the constant table... // void ConstantVector::destroyConstant() { - getRawType()->getContext().pImpl->VectorConstants.remove(this); + getType()->getContext().pImpl->VectorConstants.remove(this); destroyConstantImpl(); } /// This function will return true iff every element in this vector constant /// is set to all ones. -/// @returns true iff this constant's emements are all set to all ones. +/// @returns true iff this constant's elements are all set to all ones. /// @brief Determine if the value is all ones. bool ConstantVector::isAllOnesValue() const { // Check out first element. @@ -1068,9 +1081,10 @@ bool ConstantVector::isAllOnesValue() const { const ConstantInt *CI = dyn_cast<ConstantInt>(Elt); if (!CI || !CI->isAllOnesValue()) return false; // Then make sure all remaining elements point to the same value. - for (unsigned I = 1, E = getNumOperands(); I < E; ++I) { - if (getOperand(I) != Elt) return false; - } + for (unsigned I = 1, E = getNumOperands(); I < E; ++I) + if (getOperand(I) != Elt) + return false; + return true; } @@ -1081,7 +1095,8 @@ Constant *ConstantVector::getSplatValue() const { Constant *Elt = getOperand(0); // Then make sure all remaining elements point to the same value. for (unsigned I = 1, E = getNumOperands(); I < E; ++I) - if (getOperand(I) != Elt) return 0; + if (getOperand(I) != Elt) + return 0; return Elt; } @@ -1095,7 +1110,7 @@ ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) { // destroyConstant - Remove the constant from the constant table... // void ConstantPointerNull::destroyConstant() { - getRawType()->getContext().pImpl->NullPtrConstants.remove(this); + getType()->getContext().pImpl->NullPtrConstants.remove(this); destroyConstantImpl(); } @@ -1110,7 +1125,7 @@ UndefValue *UndefValue::get(const Type *Ty) { // destroyConstant - Remove the constant from the constant table. // void UndefValue::destroyConstant() { - getRawType()->getContext().pImpl->UndefValueConstants.remove(this); + getType()->getContext().pImpl->UndefValueConstants.remove(this); destroyConstantImpl(); } @@ -1144,7 +1159,7 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) // destroyConstant - Remove the constant from the constant table. // void BlockAddress::destroyConstant() { - getFunction()->getRawType()->getContext().pImpl + getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); getBasicBlock()->AdjustBlockAddressRefCount(-1); destroyConstantImpl(); @@ -1183,7 +1198,7 @@ void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(NewBA != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(NewBA); + replaceAllUsesWith(NewBA); destroyConstant(); } @@ -1420,49 +1435,15 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { return getFoldedCast(Instruction::BitCast, C, DstTy); } -Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, - Constant *C1, Constant *C2, - unsigned Flags) { - // Check the operands for consistency first +Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) { + // Check the operands for consistency first. assert(Opcode >= Instruction::BinaryOpsBegin && Opcode < Instruction::BinaryOpsEnd && "Invalid opcode in binary constant expression"); assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); - - if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext())) - if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) - return FC; // Fold a few common cases... - - std::vector<Constant*> argVec(1, C1); argVec.push_back(C2); - ExprMapKeyType Key(Opcode, argVec, 0, Flags); - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - -Constant *ConstantExpr::getCompareTy(unsigned short predicate, - Constant *C1, Constant *C2) { - switch (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 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 getICmp(predicate, C1, C2); - } -} - -Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, - unsigned Flags) { #ifndef NDEBUG switch (Opcode) { case Instruction::Add: @@ -1521,7 +1502,15 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, } #endif - return getTy(C1->getType(), Opcode, C1, C2, Flags); + if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2)) + return FC; // Fold a few common cases. + + std::vector<Constant*> argVec(1, C1); + argVec.push_back(C2); + ExprMapKeyType Key(Opcode, argVec, 0, Flags); + + LLVMContextImpl *pImpl = C1->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(C1->getType(), Key); } Constant *ConstantExpr::getSizeOf(const Type* Ty) { @@ -1537,8 +1526,8 @@ Constant *ConstantExpr::getSizeOf(const Type* Ty) { Constant *ConstantExpr::getAlignOf(const Type* Ty) { // alignof is implemented as: (i64) gep ({i1,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::getInt1Ty(Ty->getContext()), Ty, NULL); + const Type *AligningTy = + StructType::get(Type::getInt1Ty(Ty->getContext()), Ty, NULL); Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo()); Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0); Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1); @@ -1566,41 +1555,55 @@ Constant *ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) { Type::getInt64Ty(Ty->getContext())); } -Constant *ConstantExpr::getCompare(unsigned short pred, - Constant *C1, Constant *C2) { +Constant *ConstantExpr::getCompare(unsigned short Predicate, + Constant *C1, Constant *C2) { assert(C1->getType() == C2->getType() && "Op types should be identical!"); - return getCompareTy(pred, C1, C2); + + switch (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 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 getICmp(Predicate, C1, C2); + } } -Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C, - Constant *V1, Constant *V2) { +Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2) { assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands"); - if (ReqTy == V1->getType()) - if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) - return SC; // Fold common cases + if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2)) + return SC; // Fold common cases std::vector<Constant*> argVec(3, C); argVec[1] = V1; argVec[2] = V2; ExprMapKeyType Key(Instruction::Select, argVec); - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); + LLVMContextImpl *pImpl = C->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(V1->getType(), Key); } -template<typename IndexTy> -Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, - IndexTy const *Idxs, - unsigned NumIdx, bool InBounds) { - assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, - Idxs+NumIdx) == - cast<PointerType>(ReqTy)->getElementType() && - "GEP indices invalid!"); - +Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, + unsigned NumIdx, bool InBounds) { if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs, NumIdx)) return FC; // Fold a few common cases. + // 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(); + Type *ReqTy = Ty->getPointerTo(AS); + assert(C->getType()->isPointerTy() && "Non-pointer type for constant GetElementPtr expression"); // Look up the constant in the table first to ensure uniqueness @@ -1611,32 +1614,11 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, ArgVec.push_back(cast<Constant>(Idxs[i])); const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, InBounds ? GEPOperator::IsInBounds : 0); - - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + + LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } -template<typename IndexTy> -Constant *ConstantExpr::getGetElementPtrImpl(Constant *C, IndexTy const *Idxs, - unsigned NumIdx, bool InBounds) { - // 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 getGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx,InBounds); -} - -Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, - unsigned NumIdx, bool InBounds) { - return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); -} - -Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant *const *Idxs, - unsigned NumIdx, bool InBounds) { - return getGetElementPtrImpl(C, Idxs, NumIdx, InBounds); -} - Constant * ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) { assert(LHS->getType() == RHS->getType()); @@ -1684,39 +1666,22 @@ ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) { return pImpl->ExprConstants.getOrCreate(ResultTy, Key); } -Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, - Constant *Idx) { - if (Constant *FC = ConstantFoldExtractElementInstruction(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; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); -} - Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { assert(Val->getType()->isVectorTy() && "Tried to create extractelement operation on non-vector type!"); assert(Idx->getType()->isIntegerTy(32) && "Extractelement index must be i32 type!"); - return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(), - Val, Idx); -} - -Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, - Constant *Elt, Constant *Idx) { - if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) + + if (Constant *FC = ConstantFoldExtractElementInstruction(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(Elt); ArgVec.push_back(Idx); - const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); + const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec); - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + LLVMContextImpl *pImpl = Val->getContext().pImpl; + Type *ReqTy = cast<VectorType>(Val->getType())->getElementType(); return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } @@ -1728,21 +1693,17 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, && "Insertelement types must match!"); assert(Idx->getType()->isIntegerTy(32) && "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)) - return FC; // Fold a few common cases... + if (Constant *FC = ConstantFoldInsertElementInstruction(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, V1); - ArgVec.push_back(V2); - ArgVec.push_back(Mask); - const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); + std::vector<Constant*> ArgVec(1, Val); + ArgVec.push_back(Elt); + ArgVec.push_back(Idx); + const ExprMapKeyType Key(Instruction::InsertElement,ArgVec); - LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; - return pImpl->ExprConstants.getOrCreate(ReqTy, Key); + LLVMContextImpl *pImpl = Val->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(Val->getType(), Key); } Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, @@ -1750,62 +1711,49 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && "Invalid shuffle vector constant expr operands!"); + if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) + return FC; // Fold a few common cases. + unsigned NElts = cast<VectorType>(Mask->getType())->getNumElements(); const Type *EltTy = cast<VectorType>(V1->getType())->getElementType(); const Type *ShufTy = VectorType::get(EltTy, NElts); - return getShuffleVectorTy(ShufTy, V1, V2, Mask); -} -Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg, - Constant *Val, - const unsigned *Idxs, unsigned NumIdx) { - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs, - Idxs+NumIdx) == Val->getType() && - "insertvalue indices invalid!"); - assert(Agg->getType() == ReqTy && - "insertvalue type invalid!"); - assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant InsertValue expression"); - Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx); - assert(FC && "InsertValue constant expr couldn't be folded!"); - return FC; + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec(1, V1); + ArgVec.push_back(V2); + ArgVec.push_back(Mask); + const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec); + + LLVMContextImpl *pImpl = ShufTy->getContext().pImpl; + return pImpl->ExprConstants.getOrCreate(ShufTy, Key); } Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val, - const unsigned *IdxList, unsigned NumIdx) { - assert(Agg->getType()->isFirstClassType() && - "Tried to create insertelement operation on non-first-class type!"); - - const Type *ReqTy = Agg->getType(); -#ifndef NDEBUG - const Type *ValTy = - ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx); -#endif - assert(ValTy == Val->getType() && "insertvalue indices invalid!"); - return getInsertValueTy(ReqTy, Agg, Val, IdxList, NumIdx); -} - -Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg, - const unsigned *Idxs, unsigned NumIdx) { - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs, - Idxs+NumIdx) == ReqTy && - "extractvalue indices invalid!"); + ArrayRef<unsigned> Idxs) { + assert(ExtractValueInst::getIndexedType(Agg->getType(), + Idxs) == Val->getType() && + "insertvalue indices invalid!"); assert(Agg->getType()->isFirstClassType() && - "Non-first-class type for constant extractvalue expression"); - Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx); - assert(FC && "ExtractValue constant expr couldn't be folded!"); + "Non-first-class type for constant insertvalue expression"); + Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs); + assert(FC && "insertvalue constant expr couldn't be folded!"); return FC; } Constant *ConstantExpr::getExtractValue(Constant *Agg, - const unsigned *IdxList, unsigned NumIdx) { + ArrayRef<unsigned> Idxs) { assert(Agg->getType()->isFirstClassType() && "Tried to create extractelement operation on non-first-class type!"); - const Type *ReqTy = - ExtractValueInst::getIndexedType(Agg->getType(), IdxList, IdxList+NumIdx); + const Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs); + (void)ReqTy; assert(ReqTy && "extractvalue indices invalid!"); - return getExtractValueTy(ReqTy, Agg, IdxList, NumIdx); + + assert(Agg->getType()->isFirstClassType() && + "Non-first-class type for constant extractvalue expression"); + Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs); + assert(FC && "ExtractValue constant expr couldn't be folded!"); + return FC; } Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) { @@ -1918,7 +1866,7 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { - getRawType()->getContext().pImpl->ExprConstants.remove(this); + getType()->getContext().pImpl->ExprConstants.remove(this); destroyConstantImpl(); } @@ -1959,10 +1907,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast<Constant>(To); - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; + LLVMContextImpl *pImpl = getType()->getContext().pImpl; std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, ConstantArray*> Lookup; - Lookup.first.first = cast<ArrayType>(getRawType()); + Lookup.first.first = cast<ArrayType>(getType()); Lookup.second = this; std::vector<Constant*> &Values = Lookup.first.second; @@ -1996,7 +1944,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Constant *Replacement = 0; if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this array type already. bool Exists; @@ -2032,7 +1980,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); @@ -2047,7 +1995,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); std::pair<LLVMContextImpl::StructConstantsTy::MapKey, ConstantStruct*> Lookup; - Lookup.first.first = cast<StructType>(getRawType()); + Lookup.first.first = cast<StructType>(getType()); Lookup.second = this; std::vector<Constant*> &Values = Lookup.first.second; Values.reserve(getNumOperands()); // Build replacement struct. @@ -2069,11 +2017,11 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - LLVMContextImpl *pImpl = getRawType()->getContext().pImpl; + LLVMContextImpl *pImpl = getContext().pImpl; Constant *Replacement = 0; if (isAllZeros) { - Replacement = ConstantAggregateZero::get(getRawType()); + Replacement = ConstantAggregateZero::get(getType()); } else { // Check to see if we have this struct type already. bool Exists; @@ -2098,7 +2046,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); @@ -2116,11 +2064,11 @@ void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, Values.push_back(Val); } - Constant *Replacement = get(cast<VectorType>(getRawType()), Values); + Constant *Replacement = get(Values); assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); @@ -2151,8 +2099,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (Agg == From) Agg = To; ArrayRef<unsigned> Indices = getIndices(); - Replacement = ConstantExpr::getExtractValue(Agg, - &Indices[0], Indices.size()); + Replacement = ConstantExpr::getExtractValue(Agg, Indices); } else if (getOpcode() == Instruction::InsertValue) { Constant *Agg = getOperand(0); Constant *Val = getOperand(1); @@ -2160,11 +2107,10 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (Val == From) Val = To; ArrayRef<unsigned> Indices = getIndices(); - Replacement = ConstantExpr::getInsertValue(Agg, Val, - &Indices[0], Indices.size()); + Replacement = ConstantExpr::getInsertValue(Agg, Val, Indices); } else if (isCast()) { assert(getOperand(0) == From && "Cast only has one use!"); - Replacement = ConstantExpr::getCast(getOpcode(), To, getRawType()); + Replacement = ConstantExpr::getCast(getOpcode(), To, getType()); } else if (getOpcode() == Instruction::Select) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); @@ -2220,7 +2166,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, assert(Replacement != this && "I didn't contain From!"); // Everyone using this now uses the replacement. - uncheckedReplaceAllUsesWith(Replacement); + replaceAllUsesWith(Replacement); // Delete the old constant! destroyConstant(); diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 1395754..bd134d9 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -568,15 +568,13 @@ struct ConstantKeyData<InlineAsm> { } }; -template<class ValType, class TypeClass, class ConstantClass, +template<class ValType, class ValRefType, class TypeClass, class ConstantClass, bool HasLargeKey = false /*true for arrays and structs*/ > -class ConstantUniqueMap : public AbstractTypeUser { +class ConstantUniqueMap { 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 @@ -589,10 +587,6 @@ private: /// through the map with very large keys. InverseMapTy InverseMap; - /// AbstractTypeMap - Map for abstract type constants. - /// - AbstractTypeMapTy AbstractTypeMap; - public: typename MapTy::iterator map_begin() { return Map.begin(); } typename MapTy::iterator map_end() { return Map.end(); } @@ -629,7 +623,7 @@ private: } typename MapTy::iterator I = - Map.find(MapKey(static_cast<const TypeClass*>(CP->getRawType()), + Map.find(MapKey(static_cast<const TypeClass*>(CP->getType()), 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 @@ -639,24 +633,8 @@ private: } 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, + ConstantClass *Create(const TypeClass *Ty, ValRefType V, typename MapTy::iterator I) { ConstantClass* Result = ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); @@ -667,15 +645,13 @@ private: 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) { + ConstantClass *getOrCreate(const TypeClass *Ty, ValRefType V) { MapKey Lookup(Ty, V); ConstantClass* Result = 0; @@ -692,43 +668,6 @@ public: 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) { typename MapTy::iterator I = FindExistingElement(CP); assert(I != Map.end() && "Constant not found in constant table!"); @@ -736,12 +675,6 @@ public: 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); } @@ -755,22 +688,7 @@ public: 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. - // - // This must use getRawType() because if the type is under refinement, we - // will get the refineAbstractType callback below, and we don't want to - // kick union find in on the constant. - if (C->getRawType()->isAbstract()) { - typename AbstractTypeMapTy::iterator ATI = - AbstractTypeMap.find(cast<DerivedType>(C->getRawType())); - assert(ATI != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - if (ATI->second == OldI) - ATI->second = I; - } - - // Remove the old entry from the map. + // Remove the old entry from the map. Map.erase(OldI); // Update the inverse map so that we know that this constant is now @@ -780,58 +698,6 @@ public: InverseMap[C] = I; } } - - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - 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(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 92f9440..2a816e1 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -19,7 +19,6 @@ #include "llvm/GlobalVariable.h" #include "llvm/GlobalAlias.h" #include "llvm/LLVMContext.h" -#include "llvm/TypeSymbolTable.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" #include "llvm/PassManager.h" @@ -111,27 +110,6 @@ void LLVMSetTarget(LLVMModuleRef M, const char *Triple) { unwrap(M)->setTargetTriple(Triple); } -/*--.. Type names ..........................................................--*/ -LLVMBool LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { - return unwrap(M)->addTypeName(Name, unwrap(Ty)); -} - -void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name) { - TypeSymbolTable &TST = unwrap(M)->getTypeSymbolTable(); - - 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)); -} - -const char *LLVMGetTypeName(LLVMModuleRef M, LLVMTypeRef Ty) { - return unwrap(M)->getTypeName(unwrap(Ty)).c_str(); -} - void LLVMDumpModule(LLVMModuleRef M) { unwrap(M)->dump(); } @@ -182,8 +160,6 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { return LLVMArrayTypeKind; case Type::PointerTyID: return LLVMPointerTypeKind; - case Type::OpaqueTyID: - return LLVMOpaqueTypeKind; case Type::VectorTyID: return LLVMVectorTypeKind; case Type::X86_MMXTyID: @@ -284,10 +260,7 @@ LLVMTypeRef LLVMX86MMXType(void) { LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType, LLVMTypeRef *ParamTypes, unsigned ParamCount, LLVMBool IsVarArg) { - std::vector<const Type*> Tys; - for (LLVMTypeRef *I = ParamTypes, *E = ParamTypes + ParamCount; I != E; ++I) - Tys.push_back(unwrap(*I)); - + ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount); return wrap(FunctionType::get(unwrap(ReturnType), Tys, IsVarArg != 0)); } @@ -314,11 +287,7 @@ void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed) { - std::vector<const Type*> Tys; - for (LLVMTypeRef *I = ElementTypes, - *E = ElementTypes + ElementCount; I != E; ++I) - Tys.push_back(unwrap(*I)); - + ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount); return wrap(StructType::get(*unwrap(C), Tys, Packed != 0)); } @@ -328,6 +297,16 @@ LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, ElementCount, Packed); } +LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name) +{ + return wrap(StructType::createNamed(*unwrap(C), Name)); +} + +void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, + unsigned ElementCount, LLVMBool Packed) { + ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount); + unwrap<StructType>(StructTy)->setBody(Tys, Packed != 0); +} unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) { return unwrap<StructType>(StructTy)->getNumElements(); @@ -344,6 +323,14 @@ LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) { return unwrap<StructType>(StructTy)->isPacked(); } +LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy) { + return unwrap<StructType>(StructTy)->isOpaque(); +} + +LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { + return wrap(unwrap(M)->getTypeByName(Name)); +} + /*--.. Operations on array, pointer, and vector types (sequence types) .....--*/ LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) { @@ -382,9 +369,6 @@ LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef 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()); @@ -392,28 +376,6 @@ LLVMTypeRef LLVMVoidType(void) { LLVMTypeRef LLVMLabelType(void) { return LLVMLabelTypeInContext(LLVMGetGlobalContext()); } -LLVMTypeRef LLVMOpaqueType(void) { - return LLVMOpaqueTypeInContext(LLVMGetGlobalContext()); -} - -/*--.. Operations on type handles ..........................................--*/ - -LLVMTypeHandleRef LLVMCreateTypeHandle(LLVMTypeRef PotentiallyAbstractTy) { - return wrap(new PATypeHolder(unwrap(PotentiallyAbstractTy))); -} - -void LLVMDisposeTypeHandle(LLVMTypeHandleRef TypeHandle) { - delete unwrap(TypeHandle); -} - -LLVMTypeRef LLVMResolveTypeHandle(LLVMTypeHandleRef TypeHandle) { - return wrap(unwrap(TypeHandle)->get()); -} - -void LLVMRefineType(LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy) { - unwrap<DerivedType>(AbstractTy)->refineAbstractTypeTo(unwrap(ConcreteTy)); -} - /*===-- Operations on values ----------------------------------------------===*/ @@ -612,9 +574,10 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { - return wrap(ConstantStruct::get(*unwrap(C), - unwrap<Constant>(ConstantVals, Count), - Count, Packed != 0)); + Constant **Elements = unwrap<Constant>(ConstantVals, Count); + return wrap(ConstantStruct::getAnon(*unwrap(C), + ArrayRef<Constant*>(Elements, Count), + Packed != 0)); } LLVMValueRef LLVMConstString(const char *Str, unsigned Length, @@ -624,15 +587,24 @@ LLVMValueRef LLVMConstString(const char *Str, unsigned Length, } LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { - return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), - unwrap<Constant>(ConstantVals, Length), - Length)); + ArrayRef<Constant*> V(unwrap<Constant>(ConstantVals, Length), Length); + return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); } LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count, Packed); } + +LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, + LLVMValueRef *ConstantVals, + unsigned Count) { + Constant **Elements = unwrap<Constant>(ConstantVals, Count); + const StructType *Ty = cast<StructType>(unwrap(StructTy)); + + return wrap(ConstantStruct::get(Ty, ArrayRef<Constant*>(Elements, Count))); +} + LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { return wrap(ConstantVector::get(ArrayRef<Constant*>( unwrap<Constant>(ScalarConstantVals, Size), Size))); @@ -962,7 +934,8 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx) { return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant), - IdxList, NumIdx)); + ArrayRef<unsigned>(IdxList, + NumIdx))); } LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, @@ -970,7 +943,8 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, unsigned *IdxList, unsigned NumIdx) { return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant), unwrap<Constant>(ElementValueConstant), - IdxList, NumIdx)); + ArrayRef<unsigned>(IdxList, + NumIdx))); } LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, @@ -1706,7 +1680,7 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name) { return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), - unwrap(Args), unwrap(Args) + NumArgs, + ArrayRef<Value *>(unwrap(Args), NumArgs), Name)); } @@ -2089,8 +2063,9 @@ LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name) { - return wrap(unwrap(B)->CreateCall(unwrap(Fn), unwrap(Args), - unwrap(Args) + NumArgs, Name)); + return wrap(unwrap(B)->CreateCall(unwrap(Fn), + ArrayRef<Value *>(unwrap(Args), NumArgs), + Name)); } LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, diff --git a/lib/VMCore/DebugLoc.cpp b/lib/VMCore/DebugLoc.cpp index 520333c..4ff6b2c 100644 --- a/lib/VMCore/DebugLoc.cpp +++ b/lib/VMCore/DebugLoc.cpp @@ -128,6 +128,38 @@ DebugLoc DebugLoc::getFromDILocation(MDNode *N) { return get(LineNo, ColNo, Scope, dyn_cast_or_null<MDNode>(N->getOperand(3))); } +/// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc. +DebugLoc DebugLoc::getFromDILexicalBlock(MDNode *N) { + if (N == 0 || N->getNumOperands() < 3) return DebugLoc(); + + MDNode *Scope = dyn_cast_or_null<MDNode>(N->getOperand(1)); + if (Scope == 0) return DebugLoc(); + + unsigned LineNo = 0, ColNo = 0; + if (ConstantInt *Line = dyn_cast_or_null<ConstantInt>(N->getOperand(2))) + LineNo = Line->getZExtValue(); + if (ConstantInt *Col = dyn_cast_or_null<ConstantInt>(N->getOperand(3))) + ColNo = Col->getZExtValue(); + + return get(LineNo, ColNo, Scope, NULL); +} + +void DebugLoc::dump(const LLVMContext &Ctx) const { +#ifndef NDEBUG + if (!isUnknown()) { + dbgs() << getLine(); + if (getCol() != 0) + dbgs() << ',' << getCol(); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(getInlinedAt(Ctx)); + if (!InlinedAtDL.isUnknown()) { + dbgs() << " @ "; + InlinedAtDL.dump(Ctx); + } else + dbgs() << "\n"; + } +#endif +} + //===----------------------------------------------------------------------===// // DenseMap specialization //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 0ae0bdb..6536bcd 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -134,7 +134,7 @@ LLVMContext &Function::getContext() const { return getType()->getContext(); } -const FunctionType *Function::getFunctionType() const { +FunctionType *Function::getFunctionType() const { return cast<FunctionType>(getType()->getElementType()); } @@ -142,7 +142,7 @@ bool Function::isVarArg() const { return getFunctionType()->isVarArg(); } -const Type *Function::getReturnType() const { +Type *Function::getReturnType() const { return getFunctionType()->getReturnType(); } @@ -163,7 +163,7 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, : GlobalValue(PointerType::getUnqual(Ty), Value::FunctionVal, 0, 0, Linkage, name) { assert(FunctionType::isValidReturnType(getReturnType()) && - !getReturnType()->isOpaqueTy() && "invalid return type"); + "invalid return type"); SymTab = new ValueSymbolTable(); // If the function has arguments, mark them as lazily built. @@ -333,7 +333,7 @@ unsigned Function::getIntrinsicID() const { return 0; } -std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { +std::string Intrinsic::getName(ID id, ArrayRef<Type*> Tys) { assert(id < num_intrinsics && "Invalid intrinsic ID!"); static const char * const Table[] = { "not_intrinsic", @@ -341,10 +341,10 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_NAME_TABLE }; - if (numTys == 0) + if (Tys.empty()) return Table[id]; std::string Result(Table[id]); - for (unsigned i = 0; i < numTys; ++i) { + for (unsigned i = 0; i < Tys.size(); ++i) { if (const PointerType* PTyp = dyn_cast<PointerType>(Tys[i])) { Result += ".p" + llvm::utostr(PTyp->getAddressSpace()) + EVT::getEVT(PTyp->getElementType()).getEVTString(); @@ -356,10 +356,9 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) { } const FunctionType *Intrinsic::getType(LLVMContext &Context, - ID id, const Type **Tys, - unsigned numTys) { + ID id, ArrayRef<Type*> Tys) { const Type *ResultTy = NULL; - std::vector<const Type*> ArgTys; + std::vector<Type*> ArgTys; bool IsVarArg = false; #define GET_INTRINSIC_GENERATOR @@ -384,14 +383,12 @@ bool Intrinsic::isOverloaded(ID id) { #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_ATTRIBUTES -Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, - unsigned numTys) { +Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) { // There can never be multiple globals with the same name of different types, // because intrinsics must be a specific type. return - cast<Function>(M->getOrInsertFunction(getName(id, Tys, numTys), - getType(M->getContext(), - id, Tys, numTys))); + cast<Function>(M->getOrInsertFunction(getName(id, Tys), + getType(M->getContext(), id, Tys))); } // This defines the "Intrinsic::getIntrinsicForGCCBuiltin()" method. @@ -417,7 +414,7 @@ bool Function::hasAddressTaken(const User* *PutOffender) const { /// setjmp or other function that gcc recognizes as "returning twice". /// /// FIXME: Remove after <rdar://problem/8031714> is fixed. -/// FIXME: Is the obove FIXME valid? +/// FIXME: Is the above FIXME valid? bool Function::callsFunctionThatReturnsTwice() const { const Module *M = this->getParent(); static const char *ReturnsTwiceFns[] = { diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index 60000ad..db008e0 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -51,6 +51,7 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { setAlignment(Src->getAlignment()); setSection(Src->getSection()); setVisibility(Src->getVisibility()); + setUnnamedAddr(Src->hasUnnamedAddr()); } void GlobalValue::setAlignment(unsigned Align) { @@ -60,6 +61,20 @@ void GlobalValue::setAlignment(unsigned Align) { Alignment = Log2_32(Align) + 1; assert(getAlignment() == Align && "Alignment representation error!"); } + +bool GlobalValue::isDeclaration() const { + // Globals are definitions if they have an initializer. + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) + return GV->getNumOperands() == 0; + + // Functions are definitions if they have a body. + if (const Function *F = dyn_cast<Function>(this)) + return F->empty(); + + // Aliases are always definitions. + assert(isa<GlobalAlias>(this)); + return false; +} //===----------------------------------------------------------------------===// // GlobalVariable Implementation @@ -201,39 +216,26 @@ void GlobalAlias::eraseFromParent() { getParent()->getAliasList().erase(this); } -bool GlobalAlias::isDeclaration() const { - const GlobalValue* AV = getAliasedGlobal(); - if (AV) - return AV->isDeclaration(); - else - return false; -} - -void GlobalAlias::setAliasee(Constant *Aliasee) -{ - if (Aliasee) - assert(Aliasee->getType() == getType() && - "Alias and aliasee types should match!"); +void GlobalAlias::setAliasee(Constant *Aliasee) { + assert((!Aliasee || Aliasee->getType() == getType()) && + "Alias and aliasee types should match!"); setOperand(0, Aliasee); } const GlobalValue *GlobalAlias::getAliasedGlobal() const { const Constant *C = getAliasee(); - if (C) { - if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) - return GV; - else { - const ConstantExpr *CE = 0; - if ((CE = dyn_cast<ConstantExpr>(C)) && - (CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::GetElementPtr)) - return dyn_cast<GlobalValue>(CE->getOperand(0)); - else - llvm_unreachable("Unsupported aliasee"); - } - } - return 0; + if (C == 0) return 0; + + if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) + return GV; + + const ConstantExpr *CE = cast<ConstantExpr>(C); + assert((CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::GetElementPtr) && + "Unsupported aliasee"); + + return dyn_cast<GlobalValue>(CE->getOperand(0)); } const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const { @@ -254,7 +256,7 @@ const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) const { GV = GA->getAliasedGlobal(); if (!Visited.insert(GV)) - return NULL; + return 0; } return GV; diff --git a/lib/VMCore/IRBuilder.cpp b/lib/VMCore/IRBuilder.cpp index f2d469a..ffe961f 100644 --- a/lib/VMCore/IRBuilder.cpp +++ b/lib/VMCore/IRBuilder.cpp @@ -34,7 +34,7 @@ Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) { return GV; } -const Type *IRBuilderBase::getCurrentFunctionReturnType() const { +Type *IRBuilderBase::getCurrentFunctionReturnType() const { assert(BB && BB->getParent() && "No current function!"); return BB->getParent()->getReturnType(); } @@ -52,9 +52,9 @@ Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { return BCI; } -static CallInst *createCallHelper(Value *Callee, Value *const* Ops, - unsigned NumOps, IRBuilderBase *Builder) { - CallInst *CI = CallInst::Create(Callee, Ops, Ops + NumOps, ""); +static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops, + IRBuilderBase *Builder) { + CallInst *CI = CallInst::Create(Callee, Ops, ""); Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI); Builder->SetInstDebugLocation(CI); return CI; @@ -65,11 +65,11 @@ CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile, MDNode *TBAATag) { Ptr = getCastedInt8PtrValue(Ptr); Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) }; - const Type *Tys[] = { Ptr->getType(), Size->getType() }; + Type *Tys[] = { Ptr->getType(), Size->getType() }; Module *M = BB->getParent()->getParent(); - Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + CallInst *CI = createCallHelper(TheFn, Ops, this); // Set the TBAA info if present. if (TBAATag) @@ -85,11 +85,11 @@ CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, Src = getCastedInt8PtrValue(Src); Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; - const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; Module *M = BB->getParent()->getParent(); - Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + CallInst *CI = createCallHelper(TheFn, Ops, this); // Set the TBAA info if present. if (TBAATag) @@ -105,11 +105,11 @@ CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, Src = getCastedInt8PtrValue(Src); Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; - const Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; + Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; Module *M = BB->getParent()->getParent(); - Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys, 3); + Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, 5, this); + CallInst *CI = createCallHelper(TheFn, Ops, this); // Set the TBAA info if present. if (TBAATag) @@ -130,7 +130,7 @@ CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { Value *Ops[] = { Size, Ptr }; Module *M = BB->getParent()->getParent(); Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start); - return createCallHelper(TheFn, Ops, 2, this); + return createCallHelper(TheFn, Ops, this); } CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { @@ -145,5 +145,5 @@ CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { Value *Ops[] = { Size, Ptr }; Module *M = BB->getParent()->getParent(); Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end); - return createCallHelper(TheFn, Ops, 2, this); + return createCallHelper(TheFn, Ops, this); } diff --git a/lib/VMCore/InlineAsm.cpp b/lib/VMCore/InlineAsm.cpp index bd3667d..4a03b39 100644 --- a/lib/VMCore/InlineAsm.cpp +++ b/lib/VMCore/InlineAsm.cpp @@ -47,11 +47,11 @@ InlineAsm::InlineAsm(const PointerType *Ty, const std::string &asmString, } void InlineAsm::destroyConstant() { - getRawType()->getContext().pImpl->InlineAsms.remove(this); + getType()->getContext().pImpl->InlineAsms.remove(this); delete this; } -const FunctionType *InlineAsm::getFunctionType() const { +FunctionType *InlineAsm::getFunctionType() const { return cast<FunctionType>(getType()->getElementType()); } diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 2c8b8b2..02c0757 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -204,22 +204,10 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const { if (const InvokeInst *CI = dyn_cast<InvokeInst>(this)) return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && CI->getAttributes() == cast<InvokeInst>(I)->getAttributes(); - if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) { - if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i) - if (IVI->idx_begin()[i] != cast<InsertValueInst>(I)->idx_begin()[i]) - return false; - return true; - } - if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) { - if (EVI->getNumIndices() != cast<ExtractValueInst>(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i) - if (EVI->idx_begin()[i] != cast<ExtractValueInst>(I)->idx_begin()[i]) - return false; - return true; - } + if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) + return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); + if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) + return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); return true; } @@ -256,22 +244,10 @@ bool Instruction::isSameOperationAs(const Instruction *I) const { return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() && CI->getAttributes() == cast<InvokeInst>(I)->getAttributes(); - if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) { - if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i) - if (IVI->idx_begin()[i] != cast<InsertValueInst>(I)->idx_begin()[i]) - return false; - return true; - } - if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) { - if (EVI->getNumIndices() != cast<ExtractValueInst>(I)->getNumIndices()) - return false; - for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i) - if (EVI->idx_begin()[i] != cast<ExtractValueInst>(I)->idx_begin()[i]) - return false; - return true; - } + if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) + return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices(); + if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) + return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices(); return true; } @@ -429,8 +405,10 @@ Instruction *Instruction::clone() const { // Otherwise, enumerate and copy over metadata from the old instruction to the // new one. SmallVector<std::pair<unsigned, MDNode*>, 4> TheMDs; - getAllMetadata(TheMDs); + getAllMetadataOtherThanDebugLoc(TheMDs); for (unsigned i = 0, e = TheMDs.size(); i != e; ++i) New->setMetadata(TheMDs[i].first, TheMDs[i].second); + + New->setDebugLoc(getDebugLoc()); return New; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 8f4eabe..9baad09 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -87,11 +87,8 @@ PHINode::PHINode(const PHINode &PN) : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - Use *OL = OperandList; - for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) { - OL[i] = PN.getOperand(i); - OL[i+1] = PN.getOperand(i+1); - } + std::copy(PN.op_begin(), PN.op_end(), op_begin()); + std::copy(PN.block_begin(), PN.block_end(), block_begin()); SubclassOptionalData = PN.SubclassOptionalData; } @@ -99,31 +96,37 @@ PHINode::~PHINode() { dropHungoffUses(); } +Use *PHINode::allocHungoffUses(unsigned N) const { + // Allocate the array of Uses of the incoming values, followed by a pointer + // (with bottom bit set) to the User, followed by the array of pointers to + // the incoming basic blocks. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef) + + N * sizeof(BasicBlock*); + Use *Begin = static_cast<Use*>(::operator new(size)); + Use *End = Begin + N; + (void) new(End) Use::UserRef(const_cast<PHINode*>(this), 1); + return Use::initTags(Begin, End); +} + // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { - unsigned NumOps = getNumOperands(); - Use *OL = OperandList; - assert(Idx*2 < NumOps && "BB not in PHI node!"); - Value *Removed = OL[Idx*2]; + Value *Removed = getIncomingValue(Idx); // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // client might not expect this to happen. The code as it is thrashes the + // clients might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { - OL[i-2] = OL[i]; - OL[i-2+1] = OL[i+1]; - } + std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); + std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. - OL[NumOps-2].set(0); - OL[NumOps-2+1].set(0); - NumOperands = NumOps-2; + Op<-1>().set(0); + --NumOperands; // If the PHI node is dead, because it has zero entries, nuke it now. - if (NumOps == 2 && DeletePHIIfEmpty) { + if (getNumOperands() == 0 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -137,15 +140,18 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { /// void PHINode::growOperands() { unsigned e = getNumOperands(); - // Multiply by 1.5 and round down so the result is still even. - unsigned NumOps = e + e / 4 * 2; - if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common. + unsigned NumOps = e + e / 2; + if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common. + + Use *OldOps = op_begin(); + BasicBlock **OldBlocks = block_begin(); ReservedSpace = NumOps; - Use *OldOps = OperandList; - Use *NewOps = allocHungoffUses(NumOps); - std::copy(OldOps, OldOps + e, NewOps); - OperandList = NewOps; + OperandList = allocHungoffUses(ReservedSpace); + + std::copy(OldOps, OldOps + e, op_begin()); + std::copy(OldBlocks, OldBlocks + e, block_begin()); + Use::zap(OldOps, OldOps + e, true); } @@ -168,95 +174,42 @@ Value *PHINode::hasConstantValue() const { CallInst::~CallInst() { } -void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { - assert(NumOperands == NumParams+1 && "NumOperands not set up?"); +void CallInst::init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) { + assert(NumOperands == Args.size() + 1 && "NumOperands not set up?"); Op<-1>() = Func; +#ifndef NDEBUG const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - (void)FTy; // silence warning. - assert((NumParams == FTy->getNumParams() || - (FTy->isVarArg() && NumParams > FTy->getNumParams())) && + assert((Args.size() == FTy->getNumParams() || + (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"); - for (unsigned i = 0; i != NumParams; ++i) { + + for (unsigned i = 0; i != Args.size(); ++i) assert((i >= FTy->getNumParams() || - FTy->getParamType(i) == Params[i]->getType()) && + FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"); - OperandList[i] = Params[i]; - } -} - -void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { - assert(NumOperands == 3 && "NumOperands not set up?"); - Op<-1>() = Func; - Op<0>() = Actual1; - Op<1>() = Actual2; - - const FunctionType *FTy = - cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - (void)FTy; // silence warning. - - assert((FTy->getNumParams() == 2 || - (FTy->isVarArg() && FTy->getNumParams() < 2)) && - "Calling a function with bad signature"); - assert((0 >= FTy->getNumParams() || - FTy->getParamType(0) == Actual1->getType()) && - "Calling a function with a bad signature!"); - assert((1 >= FTy->getNumParams() || - FTy->getParamType(1) == Actual2->getType()) && - "Calling a function with a bad signature!"); -} - -void CallInst::init(Value *Func, Value *Actual) { - assert(NumOperands == 2 && "NumOperands not set up?"); - Op<-1>() = Func; - Op<0>() = Actual; - - const FunctionType *FTy = - cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - (void)FTy; // silence warning. +#endif - assert((FTy->getNumParams() == 1 || - (FTy->isVarArg() && FTy->getNumParams() == 0)) && - "Calling a function with bad signature"); - assert((0 == FTy->getNumParams() || - FTy->getParamType(0) == Actual->getType()) && - "Calling a function with a bad signature!"); + std::copy(Args.begin(), Args.end(), op_begin()); + setName(NameStr); } -void CallInst::init(Value *Func) { +void CallInst::init(Value *Func, const Twine &NameStr) { assert(NumOperands == 1 && "NumOperands not set up?"); Op<-1>() = Func; +#ifndef NDEBUG const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType()); - (void)FTy; // silence warning. assert(FTy->getNumParams() == 0 && "Calling a function with bad signature"); -} +#endif -CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name, - Instruction *InsertBefore) - : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits<CallInst>::op_end(this) - 2, - 2, InsertBefore) { - init(Func, Actual); - setName(Name); + setName(NameStr); } -CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name, - BasicBlock *InsertAtEnd) - : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) - ->getElementType())->getReturnType(), - Instruction::Call, - OperandTraits<CallInst>::op_end(this) - 2, - 2, InsertAtEnd) { - init(Func, Actual); - setName(Name); -} CallInst::CallInst(Value *Func, const Twine &Name, Instruction *InsertBefore) : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType()) @@ -264,8 +217,7 @@ CallInst::CallInst(Value *Func, const Twine &Name, Instruction::Call, OperandTraits<CallInst>::op_end(this) - 1, 1, InsertBefore) { - init(Func); - setName(Name); + init(Func, Name); } CallInst::CallInst(Value *Func, const Twine &Name, @@ -275,8 +227,7 @@ CallInst::CallInst(Value *Func, const Twine &Name, Instruction::Call, OperandTraits<CallInst>::op_end(this) - 1, 1, InsertAtEnd) { - init(Func); - setName(Name); + init(Func, Name); } CallInst::CallInst(const CallInst &CI) @@ -287,10 +238,7 @@ CallInst::CallInst(const CallInst &CI) setTailCall(CI.isTailCall()); setCallingConv(CI.getCallingConv()); - Use *OL = OperandList; - Use *InOL = CI.OperandList; - for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i) - OL[i] = InOL[i]; + std::copy(CI.op_begin(), CI.op_end(), op_begin()); SubclassOptionalData = CI.SubclassOptionalData; } @@ -366,7 +314,7 @@ static Instruction *createMalloc(Instruction *InsertBefore, // Create the call to Malloc. BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd; Module* M = BB->getParent()->getParent(); - const Type *BPTy = Type::getInt8PtrTy(BB->getContext()); + Type *BPTy = Type::getInt8PtrTy(BB->getContext()); Value *MallocFunc = MallocF; if (!MallocFunc) // prototype malloc as "void *malloc(size_t)" @@ -481,27 +429,28 @@ Instruction* CallInst::CreateFree(Value* Source, BasicBlock *InsertAtEnd) { //===----------------------------------------------------------------------===// void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - Value* const *Args, unsigned NumArgs) { - assert(NumOperands == 3+NumArgs && "NumOperands not set up?"); + ArrayRef<Value *> Args, const Twine &NameStr) { + assert(NumOperands == 3 + Args.size() && "NumOperands not set up?"); Op<-3>() = Fn; Op<-2>() = IfNormal; Op<-1>() = IfException; + +#ifndef NDEBUG const FunctionType *FTy = cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()); - (void)FTy; // silence warning. - assert(((NumArgs == FTy->getNumParams()) || - (FTy->isVarArg() && NumArgs > FTy->getNumParams())) && + assert(((Args.size() == FTy->getNumParams()) || + (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Invoking a function with bad signature"); - Use *OL = OperandList; - for (unsigned i = 0, e = NumArgs; i != e; i++) { + for (unsigned i = 0, e = Args.size(); i != e; i++) assert((i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Invoking a function with a bad signature!"); - - OL[i] = Args[i]; - } +#endif + + std::copy(Args.begin(), Args.end(), op_begin()); + setName(NameStr); } InvokeInst::InvokeInst(const InvokeInst &II) @@ -511,9 +460,7 @@ InvokeInst::InvokeInst(const InvokeInst &II) II.getNumOperands()) { setAttributes(II.getAttributes()); setCallingConv(II.getCallingConv()); - Use *OL = OperandList, *InOL = II.OperandList; - for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i) - OL[i] = InOL[i]; + std::copy(II.op_begin(), II.op_end(), op_begin()); SubclassOptionalData = II.SubclassOptionalData; } @@ -817,7 +764,7 @@ bool AllocaInst::isArrayAllocation() const { return true; } -const Type *AllocaInst::getAllocatedType() const { +Type *AllocaInst::getAllocatedType() const { return getType()->getElementType(); } @@ -1092,7 +1039,7 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI) GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &Name, Instruction *InBe) : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), + checkGEPType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, 2, InBe) { @@ -1102,7 +1049,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &Name, BasicBlock *IAE) : Instruction(PointerType::get( - checkType(getIndexedType(Ptr->getType(),Idx)), + checkGEPType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)), GetElementPtr, OperandTraits<GetElementPtrInst>::op_end(this) - 2, @@ -1120,60 +1067,50 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx, /// pointer type. /// template <typename IndexTy> -static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs, - unsigned NumIdx) { +static Type *getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs, + unsigned NumIdx) { const PointerType *PTy = dyn_cast<PointerType>(Ptr); if (!PTy) return 0; // Type isn't a pointer type! - const Type *Agg = PTy->getElementType(); + Type *Agg = PTy->getElementType(); // Handle the special case of the empty set index set, which is always valid. if (NumIdx == 0) return Agg; // If there is at least one index, the top level type must be sized, otherwise - // it cannot be 'stepped over'. We explicitly allow abstract types (those - // that contain opaque types) under the assumption that it will be resolved to - // a sane type later. - if (!Agg->isSized() && !Agg->isAbstract()) + // it cannot be 'stepped over'. + if (!Agg->isSized()) return 0; unsigned CurIdx = 1; for (; CurIdx != NumIdx; ++CurIdx) { - const CompositeType *CT = dyn_cast<CompositeType>(Agg); + CompositeType *CT = dyn_cast<CompositeType>(Agg); if (!CT || CT->isPointerTy()) return 0; IndexTy Index = Idxs[CurIdx]; if (!CT->indexValid(Index)) return 0; Agg = CT->getTypeAtIndex(Index); - - // If the new type forwards to another type, then it is in the middle - // of being refined to another type (and hence, may have dropped all - // references to what it was using before). So, use the new forwarded - // type. - if (const Type *Ty = Agg->getForwardedType()) - Agg = Ty; } return CurIdx == NumIdx ? Agg : 0; } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - Value* const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, Value* const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - Constant* const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, + Constant* const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, - uint64_t const *Idxs, - unsigned NumIdx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, + uint64_t const *Idxs, + unsigned NumIdx) { return getIndexedTypeInternal(Ptr, Idxs, NumIdx); } -const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { +Type *GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { const PointerType *PTy = dyn_cast<PointerType>(Ptr); if (!PTy) return 0; // Type isn't a pointer type! @@ -1390,27 +1327,22 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const { // InsertValueInst Class //===----------------------------------------------------------------------===// -void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, - unsigned NumIdx, const Twine &Name) { +void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, + const Twine &Name) { assert(NumOperands == 2 && "NumOperands not initialized?"); - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx, Idx + NumIdx) == - Val->getType() && "Inserted value must match indexed type!"); - Op<0>() = Agg; - Op<1>() = Val; - Indices.append(Idx, Idx + NumIdx); - setName(Name); -} + // There's no fundamental reason why we require at least one index + // (other than weirdness with &*IdxBegin being invalid; see + // getelementptr's init routine for example). But there's no + // present need to support it. + assert(Idxs.size() > 0 && "InsertValueInst must have at least one index"); -void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx, - const Twine &Name) { - assert(NumOperands == 2 && "NumOperands not initialized?"); - assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx) == Val->getType() - && "Inserted value must match indexed type!"); + assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) == + Val->getType() && "Inserted value must match indexed type!"); Op<0>() = Agg; Op<1>() = Val; - Indices.push_back(Idx); + Indices.append(Idxs.begin(), Idxs.end()); setName(Name); } @@ -1423,44 +1355,18 @@ InsertValueInst::InsertValueInst(const InsertValueInst &IVI) SubclassOptionalData = IVI.SubclassOptionalData; } -InsertValueInst::InsertValueInst(Value *Agg, - Value *Val, - unsigned Idx, - const Twine &Name, - Instruction *InsertBefore) - : Instruction(Agg->getType(), InsertValue, - OperandTraits<InsertValueInst>::op_begin(this), - 2, InsertBefore) { - init(Agg, Val, Idx, Name); -} - -InsertValueInst::InsertValueInst(Value *Agg, - Value *Val, - unsigned Idx, - const Twine &Name, - BasicBlock *InsertAtEnd) - : Instruction(Agg->getType(), InsertValue, - OperandTraits<InsertValueInst>::op_begin(this), - 2, InsertAtEnd) { - init(Agg, Val, Idx, Name); -} - //===----------------------------------------------------------------------===// // ExtractValueInst Class //===----------------------------------------------------------------------===// -void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx, - const Twine &Name) { +void ExtractValueInst::init(ArrayRef<unsigned> Idxs, const Twine &Name) { assert(NumOperands == 1 && "NumOperands not initialized?"); - Indices.append(Idx, Idx + NumIdx); - setName(Name); -} - -void ExtractValueInst::init(unsigned Idx, const Twine &Name) { - assert(NumOperands == 1 && "NumOperands not initialized?"); + // There's no fundamental reason why we require at least one index. + // But there's no present need to support it. + assert(Idxs.size() > 0 && "ExtractValueInst must have at least one index"); - Indices.push_back(Idx); + Indices.append(Idxs.begin(), Idxs.end()); setName(Name); } @@ -1476,10 +1382,9 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI) // A null type is returned if the indices are invalid for the specified // pointer type. // -const Type* ExtractValueInst::getIndexedType(const Type *Agg, - const unsigned *Idxs, - unsigned NumIdx) { - for (unsigned CurIdx = 0; CurIdx != NumIdx; ++CurIdx) { +Type *ExtractValueInst::getIndexedType(const Type *Agg, + ArrayRef<unsigned> Idxs) { + for (unsigned CurIdx = 0; CurIdx != Idxs.size(); ++CurIdx) { unsigned Index = Idxs[CurIdx]; // We can't use CompositeType::indexValid(Index) here. // indexValid() always returns true for arrays because getelementptr allows @@ -1499,20 +1404,8 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg, } Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index); - - // If the new type forwards to another type, then it is in the middle - // of being refined to another type (and hence, may have dropped all - // references to what it was using before). So, use the new forwarded - // type. - if (const Type *Ty = Agg->getForwardedType()) - Agg = Ty; } - return Agg; -} - -const Type* ExtractValueInst::getIndexedType(const Type *Agg, - unsigned Idx) { - return getIndexedType(Agg, &Idx, 1); + return const_cast<Type*>(Agg); } //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 1bd497d..ebd1e0a 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -39,6 +39,10 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { // Create the 'tbaa' metadata kind. unsigned TBAAID = getMDKindID("tbaa"); assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID; + + // Create the 'prof' metadata kind. + unsigned ProfID = getMDKindID("prof"); + assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID; } LLVMContext::~LLVMContext() { delete pImpl; } diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index ccb8dc5..504b372 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -13,6 +13,7 @@ #include "LLVMContextImpl.h" #include "llvm/Module.h" +#include "llvm/ADT/STLExtras.h" #include <algorithm> using namespace llvm; @@ -31,14 +32,10 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int8Ty(C, 8), Int16Ty(C, 16), Int32Ty(C, 32), - Int64Ty(C, 64), - AlwaysOpaqueTy(new OpaqueType(C)) { + Int64Ty(C, 64) { InlineAsmDiagHandler = 0; InlineAsmDiagContext = 0; - - // Make sure the AlwaysOpaqueTy stays alive as long as the Context. - AlwaysOpaqueTy->addRef(); - OpaqueTypes.insert(AlwaysOpaqueTy); + NamedStructTypesUniqueID = 0; } namespace { @@ -58,9 +55,7 @@ LLVMContextImpl::~LLVMContextImpl() { // will try to remove itself from OwnedModules set. This would cause // iterator invalidation if we iterated on the set directly. std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end()); - for (std::vector<Module*>::iterator I = Modules.begin(), E = Modules.end(); - I != E; ++I) - delete *I; + DeleteContainerPointers(Modules); std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(), DropReferences()); @@ -78,38 +73,22 @@ LLVMContextImpl::~LLVMContextImpl() { NullPtrConstants.freeConstants(); UndefValueConstants.freeConstants(); InlineAsms.freeConstants(); - for (IntMapTy::iterator I = IntConstants.begin(), E = IntConstants.end(); - I != E; ++I) { - delete I->second; - } - for (FPMapTy::iterator I = FPConstants.begin(), E = FPConstants.end(); - I != E; ++I) { - delete I->second; - } - AlwaysOpaqueTy->dropRef(); - for (OpaqueTypesTy::iterator I = OpaqueTypes.begin(), E = OpaqueTypes.end(); - I != E; ++I) { - (*I)->AbstractTypeUsers.clear(); - delete *I; - } + DeleteContainerSeconds(IntConstants); + DeleteContainerSeconds(FPConstants); + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector<MDNode*, 8> MDNodes; MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size()); for (FoldingSetIterator<MDNode> I = MDNodeSet.begin(), E = MDNodeSet.end(); - I != E; ++I) { + I != E; ++I) MDNodes.push_back(&*I); - } MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end()); for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(), - E = MDNodes.end(); I != E; ++I) { + E = MDNodes.end(); I != E; ++I) (*I)->destroy(); - } assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() && "Destroying all MDNodes didn't empty the Context's sets."); // Destroy MDStrings. - for (StringMap<MDString*>::iterator I = MDStringCache.begin(), - E = MDStringCache.end(); I != E; ++I) { - delete I->second; - } + DeleteContainerSeconds(MDStringCache); } diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 6ea4b48..06a6f2a 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -15,17 +15,16 @@ #ifndef LLVM_LLVMCONTEXT_IMPL_H #define LLVM_LLVMCONTEXT_IMPL_H +#include "llvm/LLVMContext.h" #include "ConstantsContext.h" #include "LeaksContext.h" -#include "TypesContext.h" -#include "llvm/LLVMContext.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Metadata.h" -#include "llvm/Assembly/Writer.h" #include "llvm/Support/ValueHandle.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallPtrSet.h" @@ -139,27 +138,30 @@ public: // on Context destruction. SmallPtrSet<MDNode*, 1> NonUniquedMDNodes; - ConstantUniqueMap<char, Type, ConstantAggregateZero> AggZeroConstants; + ConstantUniqueMap<char, char, Type, ConstantAggregateZero> AggZeroConstants; - typedef ConstantUniqueMap<std::vector<Constant*>, ArrayType, - ConstantArray, true /*largekey*/> ArrayConstantsTy; + typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>, + ArrayType, ConstantArray, true /*largekey*/> ArrayConstantsTy; ArrayConstantsTy ArrayConstants; - typedef ConstantUniqueMap<std::vector<Constant*>, StructType, - ConstantStruct, true /*largekey*/> StructConstantsTy; + typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>, + StructType, ConstantStruct, true /*largekey*/> StructConstantsTy; StructConstantsTy StructConstants; - typedef ConstantUniqueMap<std::vector<Constant*>, VectorType, - ConstantVector> VectorConstantsTy; + typedef ConstantUniqueMap<std::vector<Constant*>, ArrayRef<Constant*>, + VectorType, ConstantVector> VectorConstantsTy; VectorConstantsTy VectorConstants; - ConstantUniqueMap<char, PointerType, ConstantPointerNull> NullPtrConstants; - ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants; + ConstantUniqueMap<char, char, PointerType, ConstantPointerNull> + NullPtrConstants; + ConstantUniqueMap<char, char, Type, UndefValue> UndefValueConstants; DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses; - ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants; + ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr> + ExprConstants; - ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm> InlineAsms; + ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&, PointerType, + InlineAsm> InlineAsms; ConstantInt *TheTrueVal; ConstantInt *TheFalseVal; @@ -167,41 +169,27 @@ public: LeakDetectorImpl<Value> LLVMObjects; // 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 Type X86_MMXTy; - 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 separate 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; - - // Opaque types are not structurally uniqued, so don't use TypeMap. - typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy; - OpaqueTypesTy OpaqueTypes; - - /// Used as an abstract type that will never be resolved. - OpaqueType *const AlwaysOpaqueTy; + Type VoidTy, LabelTy, FloatTy, DoubleTy, MetadataTy; + Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; + IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty; + + + /// TypeAllocator - All dynamically allocated types are allocated from this. + /// They live forever until the context is torn down. + BumpPtrAllocator TypeAllocator; + + DenseMap<unsigned, IntegerType*> IntegerTypes; + + // TODO: Optimize FunctionTypes/AnonStructTypes! + std::map<std::vector<Type*>, FunctionType*> FunctionTypes; + std::map<std::vector<Type*>, StructType*> AnonStructTypes; + StringMap<StructType*> NamedStructTypes; + unsigned NamedStructTypesUniqueID; + + DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes; + DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes; + DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0 + DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes; /// ValueHandles - This map keeps track of all of the value handles that are diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index eb719e5..ace4dc2 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ValueHandle.h" diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index 341e527..be2fcb8 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -17,12 +17,12 @@ #include "llvm/DerivedTypes.h" #include "llvm/GVMaterializer.h" #include "llvm/LLVMContext.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/LeakDetector.h" #include "SymbolTableListTraitsImpl.h" -#include "llvm/TypeSymbolTable.h" #include <algorithm> #include <cstdarg> #include <cstdlib> @@ -60,7 +60,6 @@ template class llvm::SymbolTableListTraits<GlobalAlias, Module>; Module::Module(StringRef MID, LLVMContext& C) : Context(C), Materializer(NULL), ModuleID(MID) { ValSymTab = new ValueSymbolTable(); - TypeSymTab = new TypeSymbolTable(); NamedMDSymTab = new StringMap<NamedMDNode *>(); Context.addModule(this); } @@ -74,11 +73,10 @@ Module::~Module() { LibraryList.clear(); NamedMDList.clear(); delete ValSymTab; - delete TypeSymTab; delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); } -/// Target endian information... +/// Target endian information. Module::Endianness Module::getEndianness() const { StringRef temp = DataLayout; Module::Endianness ret = AnyEndianness; @@ -218,8 +216,8 @@ Constant *Module::getOrInsertFunction(StringRef Name, va_start(Args, RetTy); // Build the list of argument types... - std::vector<const Type*> ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector<Type*> ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); @@ -236,8 +234,8 @@ Constant *Module::getOrInsertFunction(StringRef Name, va_start(Args, RetTy); // Build the list of argument types... - std::vector<const Type*> ArgTys; - while (const Type *ArgTy = va_arg(Args, const Type*)) + std::vector<Type*> ArgTys; + while (Type *ArgTy = va_arg(Args, Type*)) ArgTys.push_back(ArgTy); va_end(Args); @@ -340,51 +338,6 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) { NamedMDList.erase(NMD); } -//===----------------------------------------------------------------------===// -// Methods for easy access to the types in the module. -// - - -// addTypeName - Insert an entry in the symbol table mapping Str to Type. If -// there is already an entry for this name, true is returned and the symbol -// table is not modified. -// -bool Module::addTypeName(StringRef Name, const Type *Ty) { - TypeSymbolTable &ST = getTypeSymbolTable(); - - if (ST.lookup(Name)) return true; // Already in symtab... - - // Not in symbol table? Set the name with the Symtab as an argument so the - // type knows what to update... - ST.insert(Name, Ty); - - return false; -} - -/// getTypeByName - Return the type with the specified name in this module, or -/// null if there is none by that name. -const Type *Module::getTypeByName(StringRef Name) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - return cast_or_null<Type>(ST.lookup(Name)); -} - -// getTypeName - If there is at least one entry in the symbol table for the -// specified type, return it. -// -std::string Module::getTypeName(const Type *Ty) const { - const TypeSymbolTable &ST = getTypeSymbolTable(); - - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - if ( TI == TE ) return ""; // No names for types - - while (TI != TE && TI->second != Ty) - ++TI; - - if (TI != TE) // Must have found an entry! - return TI->first; - return ""; // Must not have found anything... -} //===----------------------------------------------------------------------===// // Methods to control the materialization of GlobalValues in the Module. @@ -471,3 +424,130 @@ void Module::removeLibrary(StringRef Lib) { return; } } + +//===----------------------------------------------------------------------===// +// Type finding functionality. +//===----------------------------------------------------------------------===// + +namespace { + /// TypeFinder - Walk over a module, identifying all of the types that are + /// used by the module. + class TypeFinder { + // To avoid walking constant expressions multiple times and other IR + // objects, we keep several helper maps. + DenseSet<const Value*> VisitedConstants; + DenseSet<const Type*> VisitedTypes; + + std::vector<StructType*> &StructTypes; + public: + TypeFinder(std::vector<StructType*> &structTypes) + : StructTypes(structTypes) {} + + void run(const Module &M) { + // Get types from global variables. + for (Module::const_global_iterator I = M.global_begin(), + E = M.global_end(); I != E; ++I) { + incorporateType(I->getType()); + 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()); + if (const Value *Aliasee = I->getAliasee()) + incorporateValue(Aliasee); + } + + SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst; + + // 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(), + E = BB->end(); II != E; ++II) { + const Instruction &I = *II; + // Incorporate the type of the instruction and all its operands. + incorporateType(I.getType()); + for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); + OI != OE; ++OI) + incorporateValue(*OI); + + // Incorporate types hiding in metadata. + I.getAllMetadataOtherThanDebugLoc(MDForInst); + for (unsigned i = 0, e = MDForInst.size(); i != e; ++i) + incorporateMDNode(MDForInst[i].second); + MDForInst.clear(); + } + } + + for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); I != E; ++I) { + const NamedMDNode *NMD = I; + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) + incorporateMDNode(NMD->getOperand(i)); + } + } + + private: + void incorporateType(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 (StructType *STy = dyn_cast<StructType>(Ty)) + StructTypes.push_back(STy); + + // Recursively walk all contained types. + for (Type::subtype_iterator I = Ty->subtype_begin(), + E = Ty->subtype_end(); I != E; ++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 (const MDNode *M = dyn_cast<MDNode>(V)) + return incorporateMDNode(M); + if (!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 User *U = cast<User>(V); + for (Constant::const_op_iterator I = U->op_begin(), + E = U->op_end(); I != E;++I) + incorporateValue(*I); + } + + void incorporateMDNode(const MDNode *V) { + + // Already visited? + if (!VisitedConstants.insert(V).second) + return; + + // Look in operands for types. + for (unsigned i = 0, e = V->getNumOperands(); i != e; ++i) + if (Value *Op = V->getOperand(i)) + incorporateValue(Op); + } + }; +} // end anonymous namespace + +void Module::findUsedStructTypes(std::vector<StructType*> &StructTypes) const { + TypeFinder(StructTypes).run(*this); +} + + diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index e4496db..f874d1b 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -12,95 +12,17 @@ //===----------------------------------------------------------------------===// #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/ArrayRef.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" -#include "llvm/Support/Threading.h" +#include "llvm/Module.h" #include <algorithm> #include <cstdarg> +#include "llvm/ADT/SmallString.h" using namespace llvm; -// DEBUG_MERGE_TYPES - Enable this #define to see how and when derived types are -// created and later destroyed, all in an effort to make sure that there is only -// a single canonical version of a type. -// -// #define DEBUG_MERGE_TYPES 1 - -AbstractTypeUser::~AbstractTypeUser() {} - -void AbstractTypeUser::setType(Value *V, const Type *NewTy) { - V->VTy = NewTy; -} - //===----------------------------------------------------------------------===// // Type Class Implementation //===----------------------------------------------------------------------===// -/// 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 the space for their derived type to hold the contained types array of -/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are -/// allocated with the type object, decreasing allocations and eliminating the -/// need for a std::vector to be used in the Type class itself. -/// @brief Type destruction function -void Type::destroy() const { - // Nothing calls getForwardedType from here on. - if (ForwardType && ForwardType->isAbstract()) { - ForwardType->dropRef(); - ForwardType = NULL; - } - - // Structures and Functions allocate their contained types past the end of - // the type object itself. These need to be destroyed differently than the - // other types. - if (this->isFunctionTy() || this->isStructTy()) { - // First, make sure we destruct any PATypeHandles allocated by these - // subclasses. They must be manually destructed. - for (unsigned i = 0; i < NumContainedTys; ++i) - ContainedTys[i].PATypeHandle::~PATypeHandle(); - - // Now call the destructor for the subclass directly because we're going - // to delete this as an array of char. - if (this->isFunctionTy()) - static_cast<const FunctionType*>(this)->FunctionType::~FunctionType(); - else { - assert(isStructTy()); - static_cast<const StructType*>(this)->StructType::~StructType(); - } - - // Finally, remove the memory as an array deallocation of the chars it was - // constructed from. - operator delete(const_cast<Type *>(this)); - - return; - } else if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) { - LLVMContextImpl *pImpl = this->getContext().pImpl; - pImpl->OpaqueTypes.erase(opaque_this); - } - - // For all the other type subclasses, there is either no contained types or - // just one (all Sequentials). For Sequentials, the PATypeHandle is not - // allocated past the type object, its included directly in the SequentialType - // class. This means we can safely just do "normal" delete of this object and - // all the destructors that need to run will be run. - delete this; -} - -const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { +Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { switch (IDNumber) { case VoidTyID : return getVoidTy(C); case FloatTyID : return getFloatTy(C); @@ -116,15 +38,6 @@ const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) { } } -const Type *Type::getVAArgsPromotedType(LLVMContext &C) const { - if (ID == IntegerTyID && getSubclassData() < 32) - return Type::getInt32Ty(C); - else if (ID == FloatTyID) - return Type::getDoubleTy(C); - else - return this; -} - /// getScalarType - If this is a vector type, return the element type, /// otherwise return this. const Type *Type::getScalarType() const { @@ -262,13 +175,17 @@ bool Type::isSizedDerivedType() const { if (const ArrayType *ATy = dyn_cast<ArrayType>(this)) return ATy->getElementType()->isSized(); - if (const VectorType *PTy = dyn_cast<VectorType>(this)) - return PTy->getElementType()->isSized(); + if (const VectorType *VTy = dyn_cast<VectorType>(this)) + return VTy->getElementType()->isSized(); if (!this->isStructTy()) return false; - // Okay, our struct is sized if all of the elements are... + // Opaque structs have no size. + if (cast<StructType>(this)->isOpaque()) + return false; + + // Okay, our struct is sized if all of the elements are. for (subtype_iterator I = subtype_begin(), E = subtype_end(); I != E; ++I) if (!(*I)->isSized()) return false; @@ -276,696 +193,335 @@ bool Type::isSizedDerivedType() const { return true; } -/// getForwardedTypeInternal - This method is used to implement the union-find -/// algorithm for when a type is being forwarded to another type. -const Type *Type::getForwardedTypeInternal() const { - assert(ForwardType && "This type is not being forwarded to another type!"); - - // Check to see if the forwarded type has been forwarded on. If so, collapse - // the forwarding links. - const Type *RealForwardedType = ForwardType->getForwardedType(); - if (!RealForwardedType) - return ForwardType; // No it's not forwarded again - - // Yes, it is forwarded again. First thing, add the reference to the new - // forward type. - if (RealForwardedType->isAbstract()) - RealForwardedType->addRef(); - - // Now drop the old reference. This could cause ForwardType to get deleted. - // ForwardType must be abstract because only abstract types can have their own - // ForwardTypes. - ForwardType->dropRef(); - - // Return the updated type. - ForwardType = RealForwardedType; - return ForwardType; -} - -void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - llvm_unreachable("Attempting to refine a derived type!"); -} -void Type::typeBecameConcrete(const DerivedType *AbsTy) { - llvm_unreachable("DerivedType is already a concrete type!"); -} - - -std::string Type::getDescription() const { - LLVMContextImpl *pImpl = getContext().pImpl; - TypePrinting &Map = - isAbstract() ? - pImpl->AbstractTypeDescriptions : - pImpl->ConcreteTypeDescriptions; - - std::string DescStr; - raw_string_ostream DescOS(DescStr); - Map.print(this, DescOS); - return DescOS.str(); -} - - -bool StructType::indexValid(const Value *V) const { - // Structure indexes require 32-bit integer constants. - if (V->getType()->isIntegerTy(32)) - if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) - return indexValid(CU->getZExtValue()); - return false; -} - -bool StructType::indexValid(unsigned V) const { - return V < NumContainedTys; -} - -// getTypeAtIndex - Given an index value into the type, return the type of the -// element. For a structure type, this must be a constant value... -// -const Type *StructType::getTypeAtIndex(const Value *V) const { - unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue(); - return getTypeAtIndex(Idx); -} - -const Type *StructType::getTypeAtIndex(unsigned Idx) const { - assert(indexValid(Idx) && "Invalid structure index!"); - return ContainedTys[Idx]; -} - - //===----------------------------------------------------------------------===// // Primitive 'Type' data //===----------------------------------------------------------------------===// -const Type *Type::getVoidTy(LLVMContext &C) { - return &C.pImpl->VoidTy; -} - -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 Type *Type::getX86_MMXTy(LLVMContext &C) { - return &C.pImpl->X86_MMXTy; -} - -const IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { +Type *Type::getVoidTy(LLVMContext &C) { return &C.pImpl->VoidTy; } +Type *Type::getLabelTy(LLVMContext &C) { return &C.pImpl->LabelTy; } +Type *Type::getFloatTy(LLVMContext &C) { return &C.pImpl->FloatTy; } +Type *Type::getDoubleTy(LLVMContext &C) { return &C.pImpl->DoubleTy; } +Type *Type::getMetadataTy(LLVMContext &C) { return &C.pImpl->MetadataTy; } +Type *Type::getX86_FP80Ty(LLVMContext &C) { return &C.pImpl->X86_FP80Ty; } +Type *Type::getFP128Ty(LLVMContext &C) { return &C.pImpl->FP128Ty; } +Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } +Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; } + +IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; } +IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; } +IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; } +IntegerType *Type::getInt32Ty(LLVMContext &C) { return &C.pImpl->Int32Ty; } +IntegerType *Type::getInt64Ty(LLVMContext &C) { return &C.pImpl->Int64Ty; } + +IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) { return IntegerType::get(C, N); } -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) { +PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) { return getFloatTy(C)->getPointerTo(AS); } -const PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) { return getDoubleTy(C)->getPointerTo(AS); } -const PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) { return getX86_FP80Ty(C)->getPointerTo(AS); } -const PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) { return getFP128Ty(C)->getPointerTo(AS); } -const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) { return getPPC_FP128Ty(C)->getPointerTo(AS); } -const PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) { return getX86_MMXTy(C)->getPointerTo(AS); } -const PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) { +PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) { return getIntNTy(C, N)->getPointerTo(AS); } -const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) { return getInt1Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) { return getInt8Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) { return getInt16Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) { return getInt32Ty(C)->getPointerTo(AS); } -const PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) { +PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) { return getInt64Ty(C)->getPointerTo(AS); } + //===----------------------------------------------------------------------===// -// Derived Type Constructors +// IntegerType Implementation //===----------------------------------------------------------------------===// -/// isValidReturnType - Return true if the specified type is valid as a return -/// type. -bool FunctionType::isValidReturnType(const Type *RetTy) { - return !RetTy->isFunctionTy() && !RetTy->isLabelTy() && - !RetTy->isMetadataTy(); +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::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; + } + + IntegerType *&Entry = C.pImpl->IntegerTypes[NumBits]; + + if (Entry == 0) + Entry = new (C.pImpl->TypeAllocator) IntegerType(C, NumBits); + + return Entry; } -/// isValidArgumentType - Return true if the specified type is valid as an -/// argument type. -bool FunctionType::isValidArgumentType(const Type *ArgTy) { - return ArgTy->isFirstClassType() || ArgTy->isOpaqueTy(); +bool IntegerType::isPowerOf2ByteWidth() const { + unsigned BitWidth = getBitWidth(); + return (BitWidth > 7) && isPowerOf2_32(BitWidth); } -FunctionType::FunctionType(const Type *Result, - ArrayRef<const Type*> Params, +APInt IntegerType::getMask() const { + return APInt::getAllOnesValue(getBitWidth()); +} + +//===----------------------------------------------------------------------===// +// FunctionType Implementation +//===----------------------------------------------------------------------===// + +FunctionType::FunctionType(const Type *Result, ArrayRef<Type*> Params, bool IsVarArgs) - : DerivedType(Result->getContext(), FunctionTyID), isVarArgs(IsVarArgs) { - ContainedTys = reinterpret_cast<PATypeHandle*>(this+1); - NumContainedTys = Params.size() + 1; // + 1 for result type + : Type(Result->getContext(), FunctionTyID) { + Type **SubTys = reinterpret_cast<Type**>(this+1); assert(isValidReturnType(Result) && "invalid return type for function"); + setSubclassData(IsVarArgs); + SubTys[0] = const_cast<Type*>(Result); - bool isAbstract = Result->isAbstract(); - new (&ContainedTys[0]) PATypeHandle(Result, this); - - for (unsigned i = 0; i != Params.size(); ++i) { + for (unsigned i = 0, e = Params.size(); i != e; ++i) { assert(isValidArgumentType(Params[i]) && "Not a valid type for function argument!"); - new (&ContainedTys[i+1]) PATypeHandle(Params[i], this); - isAbstract |= Params[i]->isAbstract(); + SubTys[i+1] = Params[i]; } - // Calculate whether or not this type is abstract - setAbstract(isAbstract); + ContainedTys = SubTys; + NumContainedTys = Params.size() + 1; // + 1 for result type } -StructType::StructType(LLVMContext &C, - ArrayRef<const Type*> Types, bool isPacked) - : CompositeType(C, StructTyID) { - ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1); - NumContainedTys = Types.size(); - setSubclassData(isPacked); - bool isAbstract = false; - for (unsigned i = 0; i < Types.size(); ++i) { - assert(Types[i] && "<null> type for structure field!"); - assert(isValidElementType(Types[i]) && - "Invalid type for structure element!"); - new (&ContainedTys[i]) PATypeHandle(Types[i], this); - isAbstract |= Types[i]->isAbstract(); +// FunctionType::get - The factory function for the FunctionType class. +FunctionType *FunctionType::get(const Type *ReturnType, + ArrayRef<Type*> Params, bool isVarArg) { + // TODO: This is brutally slow. + std::vector<Type*> Key; + Key.reserve(Params.size()+2); + Key.push_back(const_cast<Type*>(ReturnType)); + for (unsigned i = 0, e = Params.size(); i != e; ++i) + Key.push_back(const_cast<Type*>(Params[i])); + if (isVarArg) + Key.push_back(0); + + LLVMContextImpl *pImpl = ReturnType->getContext().pImpl; + FunctionType *&FT = pImpl->FunctionTypes[Key]; + + if (FT == 0) { + FT = (FunctionType*) pImpl->TypeAllocator. + Allocate(sizeof(FunctionType) + sizeof(Type*)*(Params.size()+1), + AlignOf<FunctionType>::Alignment); + new (FT) FunctionType(ReturnType, Params, isVarArg); } - // Calculate whether or not this type is abstract - setAbstract(isAbstract); -} - -ArrayType::ArrayType(const Type *ElType, uint64_t NumEl) - : SequentialType(ArrayTyID, ElType) { - NumElements = NumEl; - - // Calculate whether or not this type is abstract - setAbstract(ElType->isAbstract()); -} - -VectorType::VectorType(const Type *ElType, unsigned NumEl) - : SequentialType(VectorTyID, ElType) { - NumElements = NumEl; - setAbstract(ElType->isAbstract()); - assert(NumEl > 0 && "NumEl of a VectorType must be greater than 0"); - assert(isValidElementType(ElType) && - "Elements of a VectorType must be a primitive type"); - -} - - -PointerType::PointerType(const Type *E, unsigned AddrSpace) - : SequentialType(PointerTyID, E) { - AddressSpace = AddrSpace; - // Calculate whether or not this type is abstract - setAbstract(E->isAbstract()); -} - -OpaqueType::OpaqueType(LLVMContext &C) : DerivedType(C, OpaqueTyID) { - setAbstract(true); -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *this << "\n"); -#endif + return FT; } -void PATypeHolder::destroy() { - Ty = 0; -} -// dropAllTypeUses - When this (abstract) type is resolved to be equal to -// another (more concrete) type, we must eliminate all references to other -// types, to avoid some circular reference problems. -void DerivedType::dropAllTypeUses() { - if (NumContainedTys != 0) { - // The type must stay abstract. To do this, we insert a pointer to a type - // that will never get resolved, thus will always be abstract. - ContainedTys[0] = getContext().pImpl->AlwaysOpaqueTy; - - // 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 AbstractTypeUser lists and - // stuff. - const Type *ConcreteTy = Type::getInt32Ty(getContext()); - for (unsigned i = 1, e = NumContainedTys; i != e; ++i) - ContainedTys[i] = ConcreteTy; - } +FunctionType *FunctionType::get(const Type *Result, bool isVarArg) { + return get(Result, ArrayRef<Type *>(), isVarArg); } -namespace { - -/// TypePromotionGraph and graph traits - this is designed to allow us to do -/// efficient SCC processing of type graphs. This is the exact same as -/// GraphTraits<Type*>, except that we pretend that concrete types have no -/// children to avoid processing them. -struct TypePromotionGraph { - Type *Ty; - TypePromotionGraph(Type *T) : Ty(T) {} -}; - -} - -namespace llvm { - template <> struct GraphTraits<TypePromotionGraph> { - typedef Type NodeType; - typedef Type::subtype_iterator ChildIteratorType; - - static inline NodeType *getEntryNode(TypePromotionGraph G) { return G.Ty; } - static inline ChildIteratorType child_begin(NodeType *N) { - if (N->isAbstract()) - return N->subtype_begin(); - // No need to process children of concrete types. - return N->subtype_end(); - } - static inline ChildIteratorType child_end(NodeType *N) { - return N->subtype_end(); - } - }; +/// isValidReturnType - Return true if the specified type is valid as a return +/// type. +bool FunctionType::isValidReturnType(const Type *RetTy) { + return !RetTy->isFunctionTy() && !RetTy->isLabelTy() && + !RetTy->isMetadataTy(); } - -// PromoteAbstractToConcrete - This is a recursive function that walks a type -// graph calculating whether or not a type is abstract. -// -void Type::PromoteAbstractToConcrete() { - if (!isAbstract()) return; - - scc_iterator<TypePromotionGraph> SI = scc_begin(TypePromotionGraph(this)); - scc_iterator<TypePromotionGraph> SE = scc_end (TypePromotionGraph(this)); - - for (; SI != SE; ++SI) { - std::vector<Type*> &SCC = *SI; - - // Concrete types are leaves in the tree. Since an SCC will either be all - // abstract or all concrete, we only need to check one type. - if (!SCC[0]->isAbstract()) continue; - - if (SCC[0]->isOpaqueTy()) - return; // Not going to be concrete, sorry. - - // If all of the children of all of the types in this SCC are concrete, - // then this SCC is now concrete as well. If not, neither this SCC, nor - // any parent SCCs will be concrete, so we might as well just exit. - for (unsigned i = 0, e = SCC.size(); i != e; ++i) - for (Type::subtype_iterator CI = SCC[i]->subtype_begin(), - E = SCC[i]->subtype_end(); CI != E; ++CI) - if ((*CI)->isAbstract()) - // If the child type is in our SCC, it doesn't make the entire SCC - // abstract unless there is a non-SCC abstract type. - if (std::find(SCC.begin(), SCC.end(), *CI) == SCC.end()) - return; // Not going to be concrete, sorry. - - // Okay, we just discovered this whole SCC is now concrete, mark it as - // such! - for (unsigned i = 0, e = SCC.size(); i != e; ++i) { - assert(SCC[i]->isAbstract() && "Why are we processing concrete types?"); - - SCC[i]->setAbstract(false); - } - - for (unsigned i = 0, e = SCC.size(); i != e; ++i) { - assert(!SCC[i]->isAbstract() && "Concrete type became abstract?"); - // The type just became concrete, notify all users! - cast<DerivedType>(SCC[i])->notifyUsesThatTypeBecameConcrete(); - } - } +/// isValidArgumentType - Return true if the specified type is valid as an +/// argument type. +bool FunctionType::isValidArgumentType(const Type *ArgTy) { + return ArgTy->isFirstClassType(); } - //===----------------------------------------------------------------------===// -// Type Structural Equality Testing +// StructType Implementation //===----------------------------------------------------------------------===// -// TypesEqual - Two types are considered structurally equal if they have the -// same "shape": Every level and element of the types have identical primitive -// ID's, and the graphs have the same edges/nodes in them. Nodes do not have to -// be pointer equals to be equivalent though. This uses an optimistic algorithm -// that assumes that two graphs are the same until proven otherwise. -// -static bool TypesEqual(const Type *Ty, const Type *Ty2, - std::map<const Type *, const Type *> &EqTypes) { - if (Ty == Ty2) return true; - if (Ty->getTypeID() != Ty2->getTypeID()) return false; - if (Ty->isOpaqueTy()) - return false; // Two unequal opaque types are never equal - - std::map<const Type*, const Type*>::iterator It = EqTypes.find(Ty); - if (It != EqTypes.end()) - return It->second == Ty2; // Looping back on a type, check for equality - - // Otherwise, add the mapping to the table to make sure we don't get - // recursion on the types... - EqTypes.insert(It, std::make_pair(Ty, Ty2)); - - // Two really annoying special cases that breaks an otherwise nice simple - // algorithm is the fact that arraytypes have sizes that differentiates types, - // and that function types can be varargs or not. Consider this now. - // - if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) { - const IntegerType *ITy2 = cast<IntegerType>(Ty2); - return ITy->getBitWidth() == ITy2->getBitWidth(); - } - - if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) { - const PointerType *PTy2 = cast<PointerType>(Ty2); - return PTy->getAddressSpace() == PTy2->getAddressSpace() && - TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes); +// Primitive Constructors. + +StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes, + bool isPacked) { + // FIXME: std::vector is horribly inefficient for this probe. + std::vector<Type*> Key; + for (unsigned i = 0, e = ETypes.size(); i != e; ++i) { + assert(isValidElementType(ETypes[i]) && + "Invalid type for structure element!"); + Key.push_back(ETypes[i]); } + if (isPacked) + Key.push_back(0); - if (const StructType *STy = dyn_cast<StructType>(Ty)) { - const StructType *STy2 = cast<StructType>(Ty2); - if (STy->getNumElements() != STy2->getNumElements()) return false; - if (STy->isPacked() != STy2->isPacked()) return false; - for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i) - if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes)) - return false; - return true; - } + StructType *&ST = Context.pImpl->AnonStructTypes[Key]; + if (ST) return ST; - if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { - const ArrayType *ATy2 = cast<ArrayType>(Ty2); - return ATy->getNumElements() == ATy2->getNumElements() && - TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes); - } + // Value not found. Create a new type! + ST = new (Context.pImpl->TypeAllocator) StructType(Context); + ST->setSubclassData(SCDB_IsAnonymous); // Anonymous struct. + ST->setBody(ETypes, isPacked); + return ST; +} + +void StructType::setBody(ArrayRef<Type*> Elements, bool isPacked) { + assert(isOpaque() && "Struct body already set!"); - if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) { - const VectorType *PTy2 = cast<VectorType>(Ty2); - return PTy->getNumElements() == PTy2->getNumElements() && - TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes); - } + setSubclassData(getSubclassData() | SCDB_HasBody); + if (isPacked) + setSubclassData(getSubclassData() | SCDB_Packed); - if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { - const FunctionType *FTy2 = cast<FunctionType>(Ty2); - if (FTy->isVarArg() != FTy2->isVarArg() || - FTy->getNumParams() != FTy2->getNumParams() || - !TypesEqual(FTy->getReturnType(), FTy2->getReturnType(), EqTypes)) - return false; - for (unsigned i = 0, e = FTy2->getNumParams(); i != e; ++i) { - if (!TypesEqual(FTy->getParamType(i), FTy2->getParamType(i), EqTypes)) - return false; - } - return true; - } + Type **Elts = getContext().pImpl-> + TypeAllocator.Allocate<Type*>(Elements.size()); + memcpy(Elts, Elements.data(), sizeof(Elements[0])*Elements.size()); - llvm_unreachable("Unknown derived type!"); - return false; -} - -namespace llvm { // in namespace llvm so findable by ADL -static bool TypesEqual(const Type *Ty, const Type *Ty2) { - std::map<const Type *, const Type *> EqTypes; - return ::TypesEqual(Ty, Ty2, EqTypes); -} -} - -// AbstractTypeHasCycleThrough - Return true there is a path from CurTy to -// TargetTy in the type graph. We know that Ty is an abstract type, so if we -// ever reach a non-abstract type, we know that we don't need to search the -// subgraph. -static bool AbstractTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy, - SmallPtrSet<const Type*, 128> &VisitedTypes) { - if (TargetTy == CurTy) return true; - if (!CurTy->isAbstract()) return false; - - if (!VisitedTypes.insert(CurTy)) - return false; // Already been here. - - for (Type::subtype_iterator I = CurTy->subtype_begin(), - E = CurTy->subtype_end(); I != E; ++I) - if (AbstractTypeHasCycleThrough(TargetTy, *I, VisitedTypes)) - return true; - return false; + ContainedTys = Elts; + NumContainedTys = Elements.size(); } -static bool ConcreteTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy, - SmallPtrSet<const Type*, 128> &VisitedTypes) { - if (TargetTy == CurTy) return true; - - if (!VisitedTypes.insert(CurTy)) - return false; // Already been here. - - for (Type::subtype_iterator I = CurTy->subtype_begin(), - E = CurTy->subtype_end(); I != E; ++I) - if (ConcreteTypeHasCycleThrough(TargetTy, *I, VisitedTypes)) - return true; - return false; +StructType *StructType::createNamed(LLVMContext &Context, StringRef Name) { + StructType *ST = new (Context.pImpl->TypeAllocator) StructType(Context); + if (!Name.empty()) + ST->setName(Name); + return ST; } -/// TypeHasCycleThroughItself - Return true if the specified type has -/// a cycle back to itself. +void StructType::setName(StringRef Name) { + if (Name == getName()) return; -namespace llvm { // in namespace llvm so it's findable by ADL -static bool TypeHasCycleThroughItself(const Type *Ty) { - SmallPtrSet<const Type*, 128> VisitedTypes; - - if (Ty->isAbstract()) { // Optimized case for abstract types. - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (AbstractTypeHasCycleThrough(Ty, *I, VisitedTypes)) - return true; - } else { - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - if (ConcreteTypeHasCycleThrough(Ty, *I, VisitedTypes)) - return true; + // If this struct already had a name, remove its symbol table entry. + if (SymbolTableEntry) { + getContext().pImpl->NamedStructTypes.erase(getName()); + SymbolTableEntry = 0; } - return false; -} -} - -//===----------------------------------------------------------------------===// -// Function Type Factory and Value Class... -// -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::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; + // If this is just removing the name, we're done. + if (Name.empty()) + return; - // First, see if the type is already in the table, for which - // a reader lock suffices. - ITy = pImpl->IntegerTypes.get(IVT); - - if (!ITy) { - // Value not found. Derive a new type! - ITy = new IntegerType(C, NumBits); - pImpl->IntegerTypes.add(IVT, ITy); + // Look up the entry for the name. + StringMapEntry<StructType*> *Entry = + &getContext().pImpl->NamedStructTypes.GetOrCreateValue(Name); + + // While we have a name collision, try a random rename. + if (Entry->getValue()) { + SmallString<64> TempStr(Name); + TempStr.push_back('.'); + raw_svector_ostream TmpStream(TempStr); + + do { + TempStr.resize(Name.size()+1); + TmpStream.resync(); + TmpStream << getContext().pImpl->NamedStructTypesUniqueID++; + + Entry = &getContext().pImpl-> + NamedStructTypes.GetOrCreateValue(TmpStream.str()); + } while (Entry->getValue()); } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *ITy << "\n"); -#endif - return ITy; -} -bool IntegerType::isPowerOf2ByteWidth() const { - unsigned BitWidth = getBitWidth(); - return (BitWidth > 7) && isPowerOf2_32(BitWidth); + // Okay, we found an entry that isn't used. It's us! + Entry->setValue(this); + + SymbolTableEntry = Entry; } -APInt IntegerType::getMask() const { - return APInt::getAllOnesValue(getBitWidth()); -} +//===----------------------------------------------------------------------===// +// StructType Helper functions. -FunctionValType FunctionValType::get(const FunctionType *FT) { - // Build up a FunctionValType - std::vector<const Type *> ParamTypes; - ParamTypes.reserve(FT->getNumParams()); - for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) - ParamTypes.push_back(FT->getParamType(i)); - return FunctionValType(FT->getReturnType(), ParamTypes, FT->isVarArg()); +StructType *StructType::get(LLVMContext &Context, bool isPacked) { + return get(Context, llvm::ArrayRef<Type*>(), isPacked); } - -// FunctionType::get - The factory function for the FunctionType class... -FunctionType *FunctionType::get(const Type *ReturnType, - ArrayRef<const Type*> Params, - bool isVarArg) { - FunctionValType VT(ReturnType, Params, isVarArg); - FunctionType *FT = 0; - - LLVMContextImpl *pImpl = ReturnType->getContext().pImpl; - - FT = pImpl->FunctionTypes.get(VT); - - if (!FT) { - FT = (FunctionType*) operator new(sizeof(FunctionType) + - sizeof(PATypeHandle)*(Params.size()+1)); - new (FT) FunctionType(ReturnType, Params, isVarArg); - pImpl->FunctionTypes.add(VT, FT); +StructType *StructType::get(Type *type, ...) { + assert(type != 0 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = type->getContext(); + va_list ap; + SmallVector<llvm::Type*, 8> StructFields; + va_start(ap, type); + while (type) { + StructFields.push_back(type); + type = va_arg(ap, llvm::Type*); } - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << FT << "\n"); -#endif - return FT; + return llvm::StructType::get(Ctx, StructFields); } -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; - - AT = pImpl->ArrayTypes.get(AVT); - - if (!AT) { - // Value not found. Derive a new type! - pImpl->ArrayTypes.add(AVT, AT = new ArrayType(ElementType, NumElements)); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *AT << "\n"); -#endif - return AT; +StructType *StructType::createNamed(LLVMContext &Context, StringRef Name, + ArrayRef<Type*> Elements, bool isPacked) { + StructType *ST = createNamed(Context, Name); + ST->setBody(Elements, isPacked); + return ST; } -bool ArrayType::isValidElementType(const Type *ElemTy) { - return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && - !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); +StructType *StructType::createNamed(StringRef Name, ArrayRef<Type*> Elements, + bool isPacked) { + assert(!Elements.empty() && + "This method may not be invoked with an empty list"); + return createNamed(Elements[0]->getContext(), Name, Elements, isPacked); } -VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) { - assert(ElementType && "Can't get vector of <null> types!"); - - VectorValType PVT(ElementType, NumElements); - VectorType *PT = 0; - - LLVMContextImpl *pImpl = ElementType->getContext().pImpl; - - PT = pImpl->VectorTypes.get(PVT); - - if (!PT) { - pImpl->VectorTypes.add(PVT, PT = new VectorType(ElementType, NumElements)); +StructType *StructType::createNamed(StringRef Name, Type *type, ...) { + assert(type != 0 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = type->getContext(); + va_list ap; + SmallVector<llvm::Type*, 8> StructFields; + va_start(ap, type); + while (type) { + StructFields.push_back(type); + type = va_arg(ap, llvm::Type*); } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *PT << "\n"); -#endif - return PT; -} - -bool VectorType::isValidElementType(const Type *ElemTy) { - return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() || - ElemTy->isOpaqueTy(); + return llvm::StructType::createNamed(Ctx, Name, StructFields); } -//===----------------------------------------------------------------------===// -// Struct Type Factory... -// - -StructType *StructType::get(LLVMContext &Context, - ArrayRef<const Type*> ETypes, - bool isPacked) { - StructValType STV(ETypes, isPacked); - StructType *ST = 0; - - LLVMContextImpl *pImpl = Context.pImpl; +StringRef StructType::getName() const { + assert(!isAnonymous() && "Anonymous structs never have names"); + if (SymbolTableEntry == 0) return StringRef(); - 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(Context, ETypes, isPacked); - pImpl->StructTypes.add(STV, ST); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *ST << "\n"); -#endif - return ST; + return ((StringMapEntry<StructType*> *)SymbolTableEntry)->getKey(); } -StructType *StructType::get(LLVMContext &Context, const Type *type, ...) { +void StructType::setBody(Type *type, ...) { + assert(type != 0 && "Cannot create a struct type with no elements with this"); va_list ap; - std::vector<const llvm::Type*> StructFields; + SmallVector<llvm::Type*, 8> StructFields; va_start(ap, type); while (type) { StructFields.push_back(type); type = va_arg(ap, llvm::Type*); } - return llvm::StructType::get(Context, StructFields); + setBody(StructFields); } bool StructType::isValidElementType(const Type *ElemTy) { @@ -973,278 +529,159 @@ bool StructType::isValidElementType(const Type *ElemTy) { !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); } - -//===----------------------------------------------------------------------===// -// Pointer Type Factory... -// - -PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) { - assert(ValueType && "Can't get a pointer to <null> type!"); - 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; - - LLVMContextImpl *pImpl = ValueType->getContext().pImpl; +/// isLayoutIdentical - Return true if this is layout identical to the +/// specified struct. +bool StructType::isLayoutIdentical(const StructType *Other) const { + if (this == Other) return true; - PT = pImpl->PointerTypes.get(PVT); + if (isPacked() != Other->isPacked() || + getNumElements() != Other->getNumElements()) + return false; - if (!PT) { - // Value not found. Derive a new type! - pImpl->PointerTypes.add(PVT, PT = new PointerType(ValueType, AddressSpace)); - } -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "Derived new type: " << *PT << "\n"); -#endif - return PT; + return std::equal(element_begin(), element_end(), Other->element_begin()); } -const PointerType *Type::getPointerTo(unsigned addrs) const { - return PointerType::get(this, addrs); -} -bool PointerType::isValidElementType(const Type *ElemTy) { - return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && - !ElemTy->isMetadataTy(); +/// getTypeByName - Return the type with the specified name, or null if there +/// is none by that name. +StructType *Module::getTypeByName(StringRef Name) const { + StringMap<StructType*>::iterator I = + getContext().pImpl->NamedStructTypes.find(Name); + if (I != getContext().pImpl->NamedStructTypes.end()) + return I->second; + return 0; } //===----------------------------------------------------------------------===// -// Opaque Type Factory... -// +// CompositeType Implementation +//===----------------------------------------------------------------------===// -OpaqueType *OpaqueType::get(LLVMContext &C) { - OpaqueType *OT = new OpaqueType(C); // All opaque types are distinct. - LLVMContextImpl *pImpl = C.pImpl; - pImpl->OpaqueTypes.insert(OT); - return OT; +Type *CompositeType::getTypeAtIndex(const Value *V) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue(); + assert(indexValid(Idx) && "Invalid structure index!"); + return STy->getElementType(Idx); + } + + return cast<SequentialType>(this)->getElementType(); +} +Type *CompositeType::getTypeAtIndex(unsigned Idx) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + assert(indexValid(Idx) && "Invalid structure index!"); + return STy->getElementType(Idx); + } + + return cast<SequentialType>(this)->getElementType(); +} +bool CompositeType::indexValid(const Value *V) const { + if (const StructType *STy = dyn_cast<StructType>(this)) { + // Structure indexes require 32-bit integer constants. + if (V->getType()->isIntegerTy(32)) + if (const ConstantInt *CU = dyn_cast<ConstantInt>(V)) + return CU->getZExtValue() < STy->getNumElements(); + return false; + } + + // Sequential types can be indexed by any integer. + return V->getType()->isIntegerTy(); } +bool CompositeType::indexValid(unsigned Idx) const { + if (const StructType *STy = dyn_cast<StructType>(this)) + return Idx < STy->getNumElements(); + // Sequential types can be indexed by any integer. + return true; +} //===----------------------------------------------------------------------===// -// Derived Type Refinement Functions +// ArrayType Implementation //===----------------------------------------------------------------------===// -// addAbstractTypeUser - Notify an abstract type that there is a new user of -// it. This function is called primarily by the PATypeHandle class. -void Type::addAbstractTypeUser(AbstractTypeUser *U) const { - assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!"); - AbstractTypeUsers.push_back(U); +ArrayType::ArrayType(Type *ElType, uint64_t NumEl) + : SequentialType(ArrayTyID, ElType) { + NumElements = NumEl; } -// removeAbstractTypeUser - Notify an abstract type that a user of the class -// no longer has a handle to the type. This function is called primarily by -// the PATypeHandle class. When there are no users of the abstract type, it -// is annihilated, because there is no way to get a reference to it ever again. -// -void Type::removeAbstractTypeUser(AbstractTypeUser *U) const { - - // 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 - // users that register and unregister users. - // - unsigned i; - for (i = AbstractTypeUsers.size(); AbstractTypeUsers[i-1] != U; --i) - assert(i != 0 && "AbstractTypeUser not in user list!"); - - --i; // Convert to be in range 0 <= i < size() - assert(i < AbstractTypeUsers.size() && "Index out of range!"); // Wraparound? - - AbstractTypeUsers.erase(AbstractTypeUsers.begin()+i); - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << " remAbstractTypeUser[" << (void*)this << ", " - << *this << "][" << i << "] User = " << U << "\n"); -#endif - - if (AbstractTypeUsers.empty() && getRefCount() == 0 && isAbstract()) { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "DELETEing unused abstract type: <" << *this - << ">[" << (void*)this << "]" << "\n"); -#endif +ArrayType *ArrayType::get(const Type *elementType, uint64_t NumElements) { + Type *ElementType = const_cast<Type*>(elementType); + assert(isValidElementType(ElementType) && "Invalid type for array element!"); + + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; + ArrayType *&Entry = + pImpl->ArrayTypes[std::make_pair(ElementType, NumElements)]; - this->destroy(); - } -} - -// refineAbstractTypeTo - This function is used when it is discovered -// that the 'this' abstract type is actually equivalent to the NewType -// specified. This causes all users of 'this' to switch to reference the more -// concrete type NewType and for 'this' to be deleted. Only used for internal -// callers. -// -void DerivedType::refineAbstractTypeTo(const Type *NewType) { - assert(isAbstract() && "refineAbstractTypeTo: Current type is not abstract!"); - 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! - pImpl->AbstractTypeDescriptions.clear(); - -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "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 to - // the type we are resolved to. - ForwardType = NewType; - if (ForwardType->isAbstract()) - ForwardType->addRef(); - - // Add a self use of the current type so that we don't delete ourself until - // after the function exits. - // - PATypeHolder CurrentTy(this); - - // To make the situation simpler, we ask the subclass to remove this type from - // the type map, and to replace any type uses with uses of non-abstract types. - // This dramatically limits the amount of recursive type trouble we can find - // ourselves in. - dropAllTypeUses(); - - // Iterate over all of the uses of this type, invoking callback. Each user - // should remove itself from our use list automatically. We have to check to - // make sure that NewTy doesn't _become_ 'this'. If it does, resolving types - // will not cause users to drop off of the use list. If we resolve to ourself - // we succeed! - // - while (!AbstractTypeUsers.empty() && NewTy != this) { - AbstractTypeUser *User = AbstractTypeUsers.back(); - - unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << " 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!"); - } - - // 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. - // This may occur on exit of this function, as the CurrentTy object is - // destroyed. -} - -// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type that -// the current type has transitioned from being abstract to being concrete. -// -void DerivedType::notifyUsesThatTypeBecameConcrete() { -#ifdef DEBUG_MERGE_TYPES - DEBUG(dbgs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n"); -#endif - - unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize; - while (!AbstractTypeUsers.empty()) { - AbstractTypeUser *ATU = AbstractTypeUsers.back(); - ATU->typeBecameConcrete(this); - - assert(AbstractTypeUsers.size() < OldSize-- && - "AbstractTypeUser did not remove itself from the use list!"); - } -} - -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void FunctionType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->FunctionTypes.RefineAbstractType(this, OldType, NewType); + if (Entry == 0) + Entry = new (pImpl->TypeAllocator) ArrayType(ElementType, NumElements); + return Entry; } -void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->FunctionTypes.TypeBecameConcrete(this, AbsTy); +bool ArrayType::isValidElementType(const Type *ElemTy) { + return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && + !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy(); } +//===----------------------------------------------------------------------===// +// VectorType Implementation +//===----------------------------------------------------------------------===// -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void ArrayType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->ArrayTypes.RefineAbstractType(this, OldType, NewType); +VectorType::VectorType(Type *ElType, unsigned NumEl) + : SequentialType(VectorTyID, ElType) { + NumElements = NumEl; } -void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->ArrayTypes.TypeBecameConcrete(this, AbsTy); +VectorType *VectorType::get(const Type *elementType, unsigned NumElements) { + Type *ElementType = const_cast<Type*>(elementType); + assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0"); + assert(isValidElementType(ElementType) && + "Elements of a VectorType must be a primitive type"); + + LLVMContextImpl *pImpl = ElementType->getContext().pImpl; + VectorType *&Entry = ElementType->getContext().pImpl + ->VectorTypes[std::make_pair(ElementType, NumElements)]; + + if (Entry == 0) + Entry = new (pImpl->TypeAllocator) VectorType(ElementType, NumElements); + return Entry; } -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void VectorType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->VectorTypes.RefineAbstractType(this, OldType, NewType); +bool VectorType::isValidElementType(const Type *ElemTy) { + return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy(); } -void VectorType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->VectorTypes.TypeBecameConcrete(this, AbsTy); -} +//===----------------------------------------------------------------------===// +// PointerType Implementation +//===----------------------------------------------------------------------===// -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void StructType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->StructTypes.RefineAbstractType(this, OldType, NewType); -} +PointerType *PointerType::get(const Type *eltTy, unsigned AddressSpace) { + Type *EltTy = const_cast<Type*>(eltTy); + assert(EltTy && "Can't get a pointer to <null> type!"); + assert(isValidElementType(EltTy) && "Invalid type for pointer element!"); + + LLVMContextImpl *CImpl = EltTy->getContext().pImpl; + + // Since AddressSpace #0 is the common case, we special case it. + PointerType *&Entry = AddressSpace == 0 ? CImpl->PointerTypes[EltTy] + : CImpl->ASPointerTypes[std::make_pair(EltTy, AddressSpace)]; -void StructType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->StructTypes.TypeBecameConcrete(this, AbsTy); + if (Entry == 0) + Entry = new (CImpl->TypeAllocator) PointerType(EltTy, AddressSpace); + return Entry; } -// refineAbstractType - Called when a contained type is found to be more -// concrete - this could potentially change us from an abstract type to a -// concrete type. -// -void PointerType::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - LLVMContextImpl *pImpl = OldType->getContext().pImpl; - pImpl->PointerTypes.RefineAbstractType(this, OldType, NewType); -} -void PointerType::typeBecameConcrete(const DerivedType *AbsTy) { - LLVMContextImpl *pImpl = AbsTy->getContext().pImpl; - pImpl->PointerTypes.TypeBecameConcrete(this, AbsTy); +PointerType::PointerType(Type *E, unsigned AddrSpace) + : SequentialType(PointerTyID, E) { + setSubclassData(AddrSpace); } -bool SequentialType::indexValid(const Value *V) const { - if (V->getType()->isIntegerTy()) - return true; - return false; +PointerType *Type::getPointerTo(unsigned addrs) const { + return PointerType::get(this, addrs); } -namespace llvm { -raw_ostream &operator<<(raw_ostream &OS, const Type &T) { - T.print(OS); - return OS; -} +bool PointerType::isValidElementType(const Type *ElemTy) { + return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() && + !ElemTy->isMetadataTy(); } diff --git a/lib/VMCore/TypeSymbolTable.cpp b/lib/VMCore/TypeSymbolTable.cpp deleted file mode 100644 index d68a44b..0000000 --- a/lib/VMCore/TypeSymbolTable.cpp +++ /dev/null @@ -1,169 +0,0 @@ -//===-- TypeSymbolTable.cpp - Implement the TypeSymbolTable class ---------===// -// -// 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 TypeSymbolTable class for the VMCore library. -// -//===----------------------------------------------------------------------===// - -#include "llvm/TypeSymbolTable.h" -#include "llvm/DerivedTypes.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -using namespace llvm; - -#define DEBUG_SYMBOL_TABLE 0 -#define DEBUG_ABSTYPE 0 - -TypeSymbolTable::~TypeSymbolTable() { - // Drop all abstract type references in the type plane... - for (iterator TI = tmap.begin(), TE = tmap.end(); TI != TE; ++TI) { - if (TI->second->isAbstract()) // If abstract, drop the reference... - cast<DerivedType>(TI->second)->removeAbstractTypeUser(this); - } -} - -std::string TypeSymbolTable::getUniqueName(StringRef BaseName) const { - std::string TryName = BaseName; - - const_iterator End = tmap.end(); - - // See if the name exists - while (tmap.find(TryName) != End) // Loop until we find a free - TryName = BaseName.str() + utostr(++LastUnique); // name in the symbol table - return TryName; -} - -// lookup a type by name - returns null on failure -Type* TypeSymbolTable::lookup(StringRef Name) const { - const_iterator TI = tmap.find(Name); - Type* result = 0; - if (TI != tmap.end()) - result = const_cast<Type*>(TI->second); - return result; -} - -// remove - Remove a type from the symbol table... -Type* TypeSymbolTable::remove(iterator Entry) { - assert(Entry != tmap.end() && "Invalid entry to remove!"); - const Type* Result = Entry->second; - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Removing Value: " << Result->getDescription() << "\n"; -#endif - - tmap.erase(Entry); - - // If we are removing an abstract type, remove the symbol table from it's use - // list... - if (Result->isAbstract()) { -#if DEBUG_ABSTYPE - dbgs() << "Removing abstract type from symtab" - << Result->getDescription() - << "\n"; -#endif - cast<DerivedType>(Result)->removeAbstractTypeUser(this); - } - - return const_cast<Type*>(Result); -} - - -// insert - Insert a type into the symbol table with the specified name... -void TypeSymbolTable::insert(StringRef Name, const Type* T) { - assert(T && "Can't insert null type into symbol table!"); - - if (tmap.insert(std::make_pair(Name, T)).second) { - // Type inserted fine with no conflict. - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Inserted type: " << Name << ": " << T->getDescription() << "\n"; -#endif - } else { - // If there is a name conflict... - - // Check to see if there is a naming conflict. If so, rename this type! - std::string UniqueName = Name; - if (lookup(Name)) - UniqueName = getUniqueName(Name); - -#if DEBUG_SYMBOL_TABLE - dump(); - dbgs() << " Inserting type: " << UniqueName << ": " - << T->getDescription() << "\n"; -#endif - - // Insert the tmap entry - tmap.insert(make_pair(UniqueName, T)); - } - - // If we are adding an abstract type, add the symbol table to it's use list. - if (T->isAbstract()) { - cast<DerivedType>(T)->addAbstractTypeUser(this); -#if DEBUG_ABSTYPE - dbgs() << "Added abstract type to ST: " << T->getDescription() << "\n"; -#endif - } -} - -// This function is called when one of the types in the type plane are refined -void TypeSymbolTable::refineAbstractType(const DerivedType *OldType, - const Type *NewType) { - // 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 - // occurrences, and although we only need to remove one at a time, it's - // faster to remove them all in one pass. - // - for (iterator I = begin(), E = end(); I != E; ++I) { - // FIXME when Types aren't const. - if (I->second == const_cast<DerivedType *>(OldType)) { -#if DEBUG_ABSTYPE - dbgs() << "Removing type " << OldType->getDescription() << "\n"; -#endif - OldType->removeAbstractTypeUser(this); - - // TODO FIXME when types aren't const - I->second = const_cast<Type *>(NewType); - if (NewType->isAbstract()) { -#if DEBUG_ABSTYPE - dbgs() << "Added type " << NewType->getDescription() << "\n"; -#endif - cast<DerivedType>(NewType)->addAbstractTypeUser(this); - } - } - } -} - - -// Handle situation where type becomes Concreate from Abstract -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. - 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 ) { - dbgs() << " '" << T.first << "' = "; - T.second->dump(); - dbgs() << "\n"; -} - -void TypeSymbolTable::dump() const { - dbgs() << "TypeSymbolPlane: "; - for_each(tmap.begin(), tmap.end(), DumpTypes); -} - diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h deleted file mode 100644 index ad09478..0000000 --- a/lib/VMCore/TypesContext.h +++ /dev/null @@ -1,426 +0,0 @@ -//===-- 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/ArrayRef.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(uint32_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(ArrayRef<const Type*> args, bool isPacked) - : ElTypes(args.vec()), 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, ArrayRef<const Type*> args, bool isVA) - : RetTy(ret), ArgTypes(args.vec()), 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; - - ~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); - } - } - } - -public: - 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; - - 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(dbgs() << "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!"); (void)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->refineAbstractTypeTo(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; - continue; - } - - if (!TypesEqual(Ty, I->second)) - continue; - - 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 - // within 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->refineAbstractTypeTo(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(dbgs() << "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(dbgs() << " " << (++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 2258b8d..359a151 100644 --- a/lib/VMCore/Use.cpp +++ b/lib/VMCore/Use.cpp @@ -135,11 +135,9 @@ void Use::zap(Use *Start, const Use *Stop, bool del) { User *Use::getUser() const { const Use *End = getImpliedUser(); - const PointerIntPair<User*, 1, unsigned>& - ref(static_cast<const AugmentedUse*>(End - 1)->ref); - User *She = ref.getPointer(); - return ref.getInt() - ? She + const UserRef *ref = reinterpret_cast<const UserRef*>(End); + return ref->getInt() + ? ref->getPointer() : (User*)End; } diff --git a/lib/VMCore/User.cpp b/lib/VMCore/User.cpp index 2f4587d..f01fa34 100644 --- a/lib/VMCore/User.cpp +++ b/lib/VMCore/User.cpp @@ -40,14 +40,12 @@ void User::replaceUsesOfWith(Value *From, Value *To) { //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N - + sizeof(AugmentedUse) - - sizeof(Use))); + // Allocate the array of Uses, followed by a pointer (with bottom bit set) to + // the User. + size_t size = N * sizeof(Use) + sizeof(Use::UserRef); + Use *Begin = static_cast<Use*>(::operator new(size)); Use *End = Begin + N; - PointerIntPair<User*, 1, unsigned>& - ref(static_cast<AugmentedUse&>(End[-1]).ref); - ref.setPointer(const_cast<User*>(this)); - ref.setInt(1); + (void) new(End) Use::UserRef(const_cast<User*>(this), 1); return Use::initTags(Begin, End); } diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 29f6a80..f1815e3 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -35,22 +35,21 @@ using namespace llvm; // Value Class //===----------------------------------------------------------------------===// -static inline const Type *checkType(const Type *Ty) { +static inline Type *checkType(const Type *Ty) { assert(Ty && "Value defined with a null type: Error!"); - return Ty; + return const_cast<Type*>(Ty); } Value::Value(const Type *ty, unsigned scid) : SubclassID(scid), HasValueHandle(0), - SubclassOptionalData(0), SubclassData(0), VTy(checkType(ty)), + SubclassOptionalData(0), SubclassData(0), VTy((Type*)checkType(ty)), UseList(0), Name(0) { + // FIXME: Why isn't this in the subclass gunk?? if (isa<CallInst>(this) || isa<InvokeInst>(this)) - assert((VTy->isFirstClassType() || VTy->isVoidTy() || - ty->isOpaqueTy() || VTy->isStructTy()) && - "invalid CallInst type!"); + assert((VTy->isFirstClassType() || VTy->isVoidTy() || VTy->isStructTy()) && + "invalid CallInst type!"); else if (!isa<Constant>(this) && !isa<BasicBlock>(this)) - assert((VTy->isFirstClassType() || VTy->isVoidTy() || - ty->isOpaqueTy()) && + assert((VTy->isFirstClassType() || VTy->isVoidTy()) && "Cannot create non-first-class values except for constants!"); } @@ -281,17 +280,16 @@ void Value::takeName(Value *V) { } -// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith, -// except that it doesn't have all of the asserts. The asserts fail because we -// are half-way done resolving types, which causes some types to exist as two -// different Type*'s at the same time. This is a sledgehammer to work around -// this problem. -// -void Value::uncheckedReplaceAllUsesWith(Value *New) { +void Value::replaceAllUsesWith(Value *New) { + assert(New && "Value::replaceAllUsesWith(<null>) is invalid!"); + assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); + assert(New->getType() == getType() && + "replaceAllUses of value with new value of different type!"); + // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); - + while (!use_empty()) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a @@ -302,18 +300,12 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { continue; } } - + U.set(New); } -} - -void Value::replaceAllUsesWith(Value *New) { - assert(New && "Value::replaceAllUsesWith(<null>) is invalid!"); - assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!"); - assert(New->getType() == getType() && - "replaceAllUses of value with new value of different type!"); - - uncheckedReplaceAllUsesWith(New); + + if (BasicBlock *BB = dyn_cast<BasicBlock>(this)) + BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New)); } Value *Value::stripPointerCasts() { diff --git a/lib/VMCore/ValueSymbolTable.cpp b/lib/VMCore/ValueSymbolTable.cpp index 254bf06..f1c9703 100644 --- a/lib/VMCore/ValueSymbolTable.cpp +++ b/lib/VMCore/ValueSymbolTable.cpp @@ -25,7 +25,7 @@ ValueSymbolTable::~ValueSymbolTable() { #ifndef NDEBUG // Only do this in -g mode... for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI) dbgs() << "Value still in symbol table! Type = '" - << VI->getValue()->getType()->getDescription() << "' Name = '" + << *VI->getValue()->getType() << "' Name = '" << VI->getKeyData() << "'\n"; assert(vmap.empty() && "Values remain in symbol table!"); #endif diff --git a/lib/VMCore/ValueTypes.cpp b/lib/VMCore/ValueTypes.cpp index c054ae4..21a1f03 100644 --- a/lib/VMCore/ValueTypes.cpp +++ b/lib/VMCore/ValueTypes.cpp @@ -133,6 +133,7 @@ std::string EVT::getEVTString() const { case MVT::v2f64: return "v2f64"; case MVT::v4f64: return "v4f64"; case MVT::Metadata:return "Metadata"; + case MVT::untyped: return "untyped"; } } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 139e035..b146b89 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -49,7 +49,6 @@ #include "llvm/Module.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" @@ -109,54 +108,6 @@ INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", static char &PreVerifyID = PreVerifier::ID; namespace { - 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? @@ -176,9 +127,6 @@ namespace { /// an instruction in the same block. SmallPtrSet<Instruction*, 16> InstsInThisBlock; - /// Types - keep track of the types that have been checked already. - TypeSet Types; - /// MDNodes - keep track of the metadata nodes that have been checked /// already. SmallPtrSet<MDNode *, 32> MDNodes; @@ -199,7 +147,6 @@ namespace { bool doInitialization(Module &M) { Mod = &M; Context = &M.getContext(); - verifyTypeSymbolTable(M.getTypeSymbolTable()); // If this is a real pass, in a pass manager, we must abort before // returning back to the pass manager, or else the pass manager may try to @@ -285,7 +232,6 @@ namespace { // Verification methods... - void verifyTypeSymbolTable(TypeSymbolTable &ST); void visitGlobalValue(GlobalValue &GV); void visitGlobalVariable(GlobalVariable &GV); void visitGlobalAlias(GlobalAlias &GA); @@ -345,7 +291,6 @@ 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; @@ -359,8 +304,7 @@ namespace { void WriteType(const Type *T) { if (!T) return; - MessagesStr << ' '; - WriteTypeSymbolic(MessagesStr, T, Mod); + MessagesStr << ' ' << *T; } @@ -568,11 +512,6 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } -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 // value of the specified type. The value V is printed in error messages. void Verifier::VerifyParameterAttrs(Attributes Attrs, const Type *Ty, @@ -1139,9 +1078,6 @@ void Verifier::visitPHINode(PHINode &PN) { 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. @@ -1195,11 +1131,11 @@ void Verifier::VerifyCallSite(CallSite CS) { } // Verify that there's no metadata unless it's a direct call to an intrinsic. - if (!CS.getCalledFunction() || + if (CS.getCalledFunction() == 0 || !CS.getCalledFunction()->getName().startswith("llvm.")) { for (FunctionType::param_iterator PI = FTy->param_begin(), PE = FTy->param_end(); PI != PE; ++PI) - Assert1(!PI->get()->isMetadataTy(), + Assert1(!(*PI)->isMetadataTy(), "Function has metadata parameter but isn't an intrinsic", I); } @@ -1382,7 +1318,7 @@ void Verifier::visitAllocaInst(AllocaInst &AI) { void Verifier::visitExtractValueInst(ExtractValueInst &EVI) { Assert1(ExtractValueInst::getIndexedType(EVI.getAggregateOperand()->getType(), - EVI.idx_begin(), EVI.idx_end()) == + EVI.getIndices()) == EVI.getType(), "Invalid ExtractValueInst operands!", &EVI); @@ -1391,7 +1327,7 @@ void Verifier::visitExtractValueInst(ExtractValueInst &EVI) { void Verifier::visitInsertValueInst(InsertValueInst &IVI) { Assert1(ExtractValueInst::getIndexedType(IVI.getAggregateOperand()->getType(), - IVI.idx_begin(), IVI.idx_end()) == + IVI.getIndices()) == IVI.getOperand(1)->getType(), "Invalid InsertValueInst operands!", &IVI); @@ -1482,8 +1418,10 @@ void Verifier::visitInstruction(Instruction &I) { // PHI nodes differ from other nodes because they actually "use" the // value in the predecessor basic blocks they correspond to. BasicBlock *UseBlock = BB; - if (isa<PHINode>(I)) - UseBlock = dyn_cast<BasicBlock>(I.getOperand(i+1)); + if (PHINode *PN = dyn_cast<PHINode>(&I)) { + unsigned j = PHINode::getIncomingValueNumForOperand(i); + UseBlock = PN->getIncomingBlock(j); + } Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB", Op, &I); @@ -1515,10 +1453,11 @@ void Verifier::visitInstruction(Instruction &I) { return; } } - } else if (isa<PHINode>(I)) { + } else if (PHINode *PN = dyn_cast<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 = dyn_cast<BasicBlock>(I.getOperand(i+1)); + unsigned j = PHINode::getIncomingValueNumForOperand(i); + BasicBlock *PredBB = PN->getIncomingBlock(j); Assert2(PredBB && (DT->dominates(OpBlock, PredBB) || !DT->isReachableFromEntry(PredBB)), "Instruction does not dominate all uses!", Op, &I); @@ -1542,69 +1481,6 @@ 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; - - Assert1(Context == &Ty->getContext(), - "Type context does not match Module context!", Ty); - - 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 |