diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 127 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 14 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/IR/Function.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/IR/Globals.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/IR/Module.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneModule.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CodeExtractor.cpp | 7 |
13 files changed, 158 insertions, 91 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index c156a60ffa7..be44fd04324 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1317,7 +1317,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy, const std::string &Name) { if (auto *FT = dyn_cast<FunctionType>(PTy->getElementType())) - return Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); + return Function::Create(FT, GlobalValue::ExternalWeakLinkage, + PTy->getAddressSpace(), Name, M); else return new GlobalVariable(*M, PTy->getElementType(), false, GlobalValue::ExternalWeakLinkage, nullptr, Name, @@ -1325,11 +1326,33 @@ static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy, PTy->getAddressSpace()); } +Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty, + Value *Val, bool IsCall) { + if (Val->getType() == Ty) + return Val; + // For calls we also accept variables in the program address space. + Type *SuggestedTy = Ty; + if (IsCall && isa<PointerType>(Ty)) { + Type *TyInProgAS = cast<PointerType>(Ty)->getElementType()->getPointerTo( + M->getDataLayout().getProgramAddressSpace()); + SuggestedTy = TyInProgAS; + if (Val->getType() == TyInProgAS) + return Val; + } + if (Ty->isLabelTy()) + Error(Loc, "'" + Name + "' is not a basic block"); + else + Error(Loc, "'" + Name + "' defined with type '" + + getTypeString(Val->getType()) + "' but expected '" + + getTypeString(SuggestedTy) + "'"); + return nullptr; +} + /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, - LocTy Loc) { + LocTy Loc, bool IsCall) { PointerType *PTy = dyn_cast<PointerType>(Ty); if (!PTy) { Error(Loc, "global variable reference must have pointer type"); @@ -1349,12 +1372,9 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, } // If we have the value in the symbol table or fwd-ref table, return it. - if (Val) { - if (Val->getType() == Ty) return Val; - Error(Loc, "'@" + Name + "' defined with type '" + - getTypeString(Val->getType()) + "'"); - return nullptr; - } + if (Val) + return cast_or_null<GlobalValue>( + checkValidVariableType(Loc, "@" + Name, Ty, Val, IsCall)); // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, Name); @@ -1362,7 +1382,8 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, return FwdVal; } -GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { +GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc, + bool IsCall) { PointerType *PTy = dyn_cast<PointerType>(Ty); if (!PTy) { Error(Loc, "global variable reference must have pointer type"); @@ -1380,12 +1401,9 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { } // If we have the value in the symbol table or fwd-ref table, return it. - if (Val) { - if (Val->getType() == Ty) return Val; - Error(Loc, "'@" + Twine(ID) + "' defined with type '" + - getTypeString(Val->getType()) + "'"); - return nullptr; - } + if (Val) + return cast_or_null<GlobalValue>( + checkValidVariableType(Loc, "@" + Twine(ID), Ty, Val, IsCall)); // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal = createGlobalFwdRef(M, PTy, ""); @@ -1500,8 +1518,8 @@ bool LLParser::ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { /// ParseOptionalAddrSpace /// := /*empty*/ /// := 'addrspace' '(' uint32 ')' -bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { - AddrSpace = 0; +bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) { + AddrSpace = DefaultAS; if (!EatIfPresent(lltok::kw_addrspace)) return false; return ParseToken(lltok::lparen, "expected '(' in address space") || @@ -2741,19 +2759,6 @@ bool LLParser::PerFunctionState::FinishFunction() { return false; } -static bool isValidVariableType(Module *M, Type *Ty, Value *Val, bool IsCall) { - if (Val->getType() == Ty) - return true; - // For calls we also accept variables in the program address space - if (IsCall && isa<PointerType>(Ty)) { - Type *TyInProgAS = cast<PointerType>(Ty)->getElementType()->getPointerTo( - M->getDataLayout().getProgramAddressSpace()); - if (Val->getType() == TyInProgAS) - return true; - } - return false; -} - /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. @@ -2771,16 +2776,8 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, } // If we have the value in the symbol table or fwd-ref table, return it. - if (Val) { - if (isValidVariableType(P.M, Ty, Val, IsCall)) - return Val; - if (Ty->isLabelTy()) - P.Error(Loc, "'%" + Name + "' is not a basic block"); - else - P.Error(Loc, "'%" + Name + "' defined with type '" + - getTypeString(Val->getType()) + "'"); - return nullptr; - } + if (Val) + return P.checkValidVariableType(Loc, "%" + Name, Ty, Val, IsCall); // Don't make placeholders with invalid type. if (!Ty->isFirstClassType()) { @@ -2814,16 +2811,8 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, } // If we have the value in the symbol table or fwd-ref table, return it. - if (Val) { - if (isValidVariableType(P.M, Ty, Val, IsCall)) - return Val; - if (Ty->isLabelTy()) - P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block"); - else - P.Error(Loc, "'%" + Twine(ID) + "' defined with type '" + - getTypeString(Val->getType()) + "'"); - return nullptr; - } + if (Val) + return P.checkValidVariableType(Loc, "%" + Twine(ID), Ty, Val, IsCall); if (!Ty->isFirstClassType()) { P.Error(Loc, "invalid use of a non-first-class type"); @@ -4940,10 +4929,10 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return false; } case ValID::t_GlobalName: - V = GetGlobalVal(ID.StrVal, Ty, ID.Loc); + V = GetGlobalVal(ID.StrVal, Ty, ID.Loc, IsCall); return V == nullptr; case ValID::t_GlobalID: - V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc); + V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc, IsCall); return V == nullptr; case ValID::t_APSInt: if (!Ty->isIntegerTy()) @@ -5086,8 +5075,8 @@ bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, /// FunctionHeader /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility /// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName -/// '(' ArgList ')' OptFuncAttrs OptSection OptionalAlign OptGC -/// OptionalPrefix OptionalPrologue OptPersonalityFn +/// '(' ArgList ')' OptAddrSpace OptFuncAttrs OptSection OptionalAlign +/// OptGC OptionalPrefix OptionalPrologue OptPersonalityFn bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { // Parse the linkage. LocTy LinkageLoc = Lex.getLoc(); @@ -5165,6 +5154,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Alignment; std::string GC; GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; + unsigned AddrSpace = 0; Constant *Prefix = nullptr; Constant *Prologue = nullptr; Constant *PersonalityFn = nullptr; @@ -5172,6 +5162,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalUnnamedAddr(UnnamedAddr) || + ParseOptionalProgramAddrSpace(AddrSpace) || ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false, BuiltinLoc) || (EatIfPresent(lltok::kw_section) && @@ -5216,7 +5207,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); - PointerType *PFT = PointerType::getUnqual(FT); + PointerType *PFT = PointerType::get(FT, AddrSpace); Fn = nullptr; if (!FunctionName.empty()) { @@ -5230,8 +5221,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { "function as global value!"); if (Fn->getType() != PFT) return Error(FRVI->second.second, "invalid forward reference to " - "function '" + FunctionName + "' with wrong type!"); - + "function '" + FunctionName + "' with wrong type: " + "expected '" + getTypeString(PFT) + "' but was '" + + getTypeString(Fn->getType()) + "'"); ForwardRefVals.erase(FRVI); } else if ((Fn = M->getFunction(FunctionName))) { // Reject redefinitions. @@ -5249,16 +5241,21 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn = cast<Function>(I->second.first); if (Fn->getType() != PFT) return Error(NameLoc, "type of definition and forward reference of '@" + - Twine(NumberedVals.size()) + "' disagree"); + Twine(NumberedVals.size()) + "' disagree: " + "expected '" + getTypeString(PFT) + "' but was '" + + getTypeString(Fn->getType()) + "'"); ForwardRefValIDs.erase(I); } } if (!Fn) - Fn = Function::Create(FT, GlobalValue::ExternalLinkage, FunctionName, M); + Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace, + FunctionName, M); else // Move the forward-reference to the correct spot in the module. M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn); + assert(Fn->getAddressSpace() == AddrSpace && "Created function in wrong AS"); + if (FunctionName.empty()) NumberedVals.push_back(Fn); @@ -5777,6 +5774,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { std::vector<unsigned> FwdRefAttrGrps; LocTy NoBuiltinLoc; unsigned CC; + unsigned InvokeAddrSpace; Type *RetType = nullptr; LocTy RetTypeLoc; ValID CalleeID; @@ -5785,6 +5783,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { BasicBlock *NormalBB, *UnwindBB; if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || + ParseOptionalProgramAddrSpace(InvokeAddrSpace) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, @@ -5816,8 +5815,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // Look up the callee. Value *Callee; - if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS, - /*IsCall=*/true)) + if (ConvertValIDToValue(PointerType::get(Ty, InvokeAddrSpace), CalleeID, + Callee, &PFS, /*IsCall=*/true)) return true; // Set up the Attribute for the function. @@ -6360,6 +6359,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, AttrBuilder RetAttrs, FnAttrs; std::vector<unsigned> FwdRefAttrGrps; LocTy BuiltinLoc; + unsigned CallAddrSpace; unsigned CC; Type *RetType = nullptr; LocTy RetTypeLoc; @@ -6376,6 +6376,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FastMathFlags FMF = EatFastMathFlagsIfPresent(); if (ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) || + ParseOptionalProgramAddrSpace(CallAddrSpace) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail, @@ -6408,8 +6409,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // Look up the callee. Value *Callee; - if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS, - /*IsCall=*/true)) + if (ConvertValIDToValue(PointerType::get(Ty, CallAddrSpace), CalleeID, Callee, + &PFS, /*IsCall=*/true)) return true; // Set up the Attribute for the function. diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 811f96418fa..cec1a8e8f7e 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -202,8 +202,9 @@ namespace llvm { /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. - GlobalValue *GetGlobalVal(const std::string &Name, Type *Ty, LocTy Loc); - GlobalValue *GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc); + GlobalValue *GetGlobalVal(const std::string &N, Type *Ty, LocTy Loc, + bool IsCall); + GlobalValue *GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall); /// Get a Comdat with the specified name, creating a forward reference /// record if needed. @@ -267,7 +268,11 @@ namespace llvm { bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr); - bool ParseOptionalAddrSpace(unsigned &AddrSpace); + bool ParseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS = 0); + bool ParseOptionalProgramAddrSpace(unsigned &AddrSpace) { + return ParseOptionalAddrSpace( + AddrSpace, M->getDataLayout().getProgramAddressSpace()); + }; bool ParseOptionalParamAttrs(AttrBuilder &B); bool ParseOptionalReturnAttrs(AttrBuilder &B); bool ParseOptionalLinkage(unsigned &Res, bool &HasLinkage, @@ -448,6 +453,9 @@ namespace llvm { bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS, bool IsCall); + Value *checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty, + Value *Val, bool IsCall); + bool parseConstantValue(Type *Ty, Constant *&C); bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS); bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) { diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index c45b441238b..48a95970733 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2938,7 +2938,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { // v1: [type, callingconv, isproto, linkage, paramattr, alignment, section, // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat, - // prefixdata, personalityfn, preemption specifier] (name in VST) + // prefixdata, personalityfn, preemption specifier, addrspace] (name in VST) // v2: [strtab_offset, strtab_size, v1] StringRef Name; std::tie(Name, Record) = readNameFromStrtab(Record); @@ -2957,8 +2957,12 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (CC & ~CallingConv::MaxID) return error("Invalid calling convention ID"); - Function *Func = - Function::Create(FTy, GlobalValue::ExternalLinkage, Name, TheModule); + unsigned AddrSpace = TheModule->getDataLayout().getProgramAddressSpace(); + if (Record.size() > 16) + AddrSpace = Record[16]; + + Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, + AddrSpace, Name, TheModule); Func->setCallingConv(CC); bool isProto = Record[2]; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 8282703d95d..c768021a0a4 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1264,7 +1264,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { // FUNCTION: [strtab offset, strtab size, type, callingconv, isproto, // linkage, paramattrs, alignment, section, visibility, gc, // unnamed_addr, prologuedata, dllstorageclass, comdat, - // prefixdata, personalityfn, DSO_Local] + // prefixdata, personalityfn, DSO_Local, addrspace] Vals.push_back(addToStrtab(F.getName())); Vals.push_back(F.getName().size()); Vals.push_back(VE.getTypeID(F.getFunctionType())); @@ -1287,6 +1287,8 @@ void ModuleBitcodeWriter::writeModuleInfo() { F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0); Vals.push_back(F.isDSOLocal()); + Vals.push_back(F.getAddressSpace()); + unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); Vals.clear(); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 27894c50bc9..1de4bac4435 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -3350,6 +3350,13 @@ void AssemblyWriter::printFunction(const Function *F) { StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr()); if (!UA.empty()) Out << ' ' << UA; + // We print the function address space if it is non-zero or if we are writing + // a module with a non-zero program address space or if there is no valid + // Module* so that the file can be parsed without the datalayout string. + const Module *Mod = F->getParent(); + if (F->getAddressSpace() != 0 || !Mod || + Mod->getDataLayout().getProgramAddressSpace() != 0) + Out << " addrspace(" << F->getAddressSpace() << ")"; if (Attrs.hasAttributes(AttributeList::FunctionIndex)) Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes()); if (F->hasSection()) { @@ -3487,6 +3494,23 @@ void AssemblyWriter::printInfoComment(const Value &V) { AnnotationWriter->printInfoComment(V, Out); } +static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I, + raw_ostream &Out) { + // We print the address space of the call if it is non-zero. + unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace(); + bool PrintAddrSpace = CallAddrSpace != 0; + if (!PrintAddrSpace) { + const Module *Mod = getModuleFromVal(I); + // We also print it if it is zero but not equal to the program address space + // or if we can't find a valid Module* to make it possible to parse + // the resulting file even without a datalayout string. + if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0) + PrintAddrSpace = true; + } + if (PrintAddrSpace) + Out << " addrspace(" << CallAddrSpace << ")"; +} + // This member is called for each Instruction in a function.. void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); @@ -3684,6 +3708,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.hasAttributes(AttributeList::ReturnIndex)) Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex); + // Only print addrspace(N) if necessary: + maybePrintCallAddrSpace(Operand, &I, Out); + // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, // and if the return type is not a pointer to a function. @@ -3726,6 +3753,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.hasAttributes(AttributeList::ReturnIndex)) Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex); + // Only print addrspace(N) if necessary: + maybePrintCallAddrSpace(Operand, &I, Out); + // If possible, print out the short form of the invoke instruction. We can // only do this if the first argument is a pointer to a nonvararg function, // and if the return type is not a pointer to a function. diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 1864ad29b30..06db01fc196 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -464,7 +464,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // the end of the name. Change name from llvm.arm.neon.vclz.* to // llvm.ctlz.* FunctionType* fType = FunctionType::get(F->getReturnType(), args, false); - NewFn = Function::Create(fType, F->getLinkage(), + NewFn = Function::Create(fType, F->getLinkage(), F->getAddressSpace(), "llvm.ctlz." + Name.substr(14), F->getParent()); return true; } @@ -480,7 +480,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // Can't use Intrinsic::getDeclaration here as the return types might // then only be structurally equal. FunctionType* fType = FunctionType::get(F->getReturnType(), Tys, false); - NewFn = Function::Create(fType, F->getLinkage(), + NewFn = Function::Create(fType, F->getLinkage(), F->getAddressSpace(), "llvm." + Name + ".p0i8", F->getParent()); return true; } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 72090f5bac3..36ba8d0721f 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -203,6 +203,11 @@ unsigned Function::getInstructionCount() { return NumInstrs; } +Function *Function::Create(FunctionType *Ty, LinkageTypes Linkage, + const Twine &N, Module &M) { + return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M); +} + void Function::removeFromParent() { getParent()->getFunctionList().remove(getIterator()); } @@ -215,10 +220,19 @@ void Function::eraseFromParent() { // Function Implementation //===----------------------------------------------------------------------===// -Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name, - Module *ParentModule) +static unsigned computeAddrSpace(unsigned AddrSpace, Module *M) { + // If AS == -1 and we are passed a valid module pointer we place the function + // in the program address space. Otherwise we default to AS0. + if (AddrSpace == static_cast<unsigned>(-1)) + return M ? M->getDataLayout().getProgramAddressSpace() : 0; + return AddrSpace; +} + +Function::Function(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, + const Twine &name, Module *ParentModule) : GlobalObject(Ty, Value::FunctionVal, - OperandTraits<Function>::op_begin(this), 0, Linkage, name), + OperandTraits<Function>::op_begin(this), 0, Linkage, name, + computeAddrSpace(AddrSpace, ParentModule)), NumArgs(Ty->getNumParams()) { assert(FunctionType::isValidReturnType(getReturnType()) && "invalid return type"); diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 20b2334a626..3f57b1dbfa8 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -108,6 +108,11 @@ unsigned GlobalValue::getAlignment() const { return cast<GlobalObject>(this)->getAlignment(); } +unsigned GlobalValue::getAddressSpace() const { + PointerType *PtrTy = getType(); + return PtrTy->getAddressSpace(); +} + void GlobalObject::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index f1802406353..882ab106a37 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -145,7 +145,8 @@ Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty, GlobalValue *F = getNamedValue(Name); if (!F) { // Nope, add it - Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name); + Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, + DL.getProgramAddressSpace(), Name); if (!New->isIntrinsic()) // Intrinsics get attrs set on construction New->setAttributes(AttributeList); FunctionList.push_back(New); @@ -154,8 +155,9 @@ Constant *Module::getOrInsertFunction(StringRef Name, FunctionType *Ty, // If the function exists but has the wrong type, return a bitcast to the // right type. - if (F->getType() != PointerType::getUnqual(Ty)) - return ConstantExpr::getBitCast(F, PointerType::getUnqual(Ty)); + auto *PTy = PointerType::get(Ty, F->getAddressSpace()); + if (F->getType() != PTy) + return ConstantExpr::getBitCast(F, PTy); // Otherwise, we just found the existing function or a prototype. return F; diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index bb0e4379d1a..89b237c391e 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -645,8 +645,8 @@ DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName, GlobalValue::LinkageTypes NewFLink, FunctionType *NewFT) { FunctionType *FT = F->getFunctionType(); - Function *NewF = Function::Create(NewFT, NewFLink, NewFName, - F->getParent()); + Function *NewF = Function::Create(NewFT, NewFLink, F->getAddressSpace(), + NewFName, F->getParent()); NewF->copyAttributesFrom(F); NewF->removeAttributes( AttributeList::ReturnIndex, @@ -819,7 +819,8 @@ bool DataFlowSanitizer::runOnModule(Module &M) { // easily identify cases of mismatching ABIs. if (getInstrumentedABI() == IA_Args && !IsZeroArgsVoidRet) { FunctionType *NewFT = getArgsFunctionType(FT); - Function *NewF = Function::Create(NewFT, F.getLinkage(), "", &M); + Function *NewF = Function::Create(NewFT, F.getLinkage(), + F.getAddressSpace(), "", &M); NewF->copyAttributesFrom(&F); NewF->removeAttributes( AttributeList::ReturnIndex, diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 80736034005..5dbe6e9ac76 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -235,8 +235,8 @@ Function *llvm::CloneFunction(Function *F, ValueToValueMapTy &VMap, ArgTypes, F->getFunctionType()->isVarArg()); // Create the new function... - Function *NewF = - Function::Create(FTy, F->getLinkage(), F->getName(), F->getParent()); + Function *NewF = Function::Create(FTy, F->getLinkage(), F->getAddressSpace(), + F->getName(), F->getParent()); // Loop over the arguments, copying the names of the mapped arguments over... Function::arg_iterator DestI = NewF->arg_begin(); diff --git a/llvm/lib/Transforms/Utils/CloneModule.cpp b/llvm/lib/Transforms/Utils/CloneModule.cpp index c7d68bab817..659993aa547 100644 --- a/llvm/lib/Transforms/Utils/CloneModule.cpp +++ b/llvm/lib/Transforms/Utils/CloneModule.cpp @@ -74,8 +74,9 @@ std::unique_ptr<Module> llvm::CloneModule( // Loop over the functions in the module, making external functions as before for (const Function &I : M) { - Function *NF = Function::Create(cast<FunctionType>(I.getValueType()), - I.getLinkage(), I.getName(), New.get()); + Function *NF = + Function::Create(cast<FunctionType>(I.getValueType()), I.getLinkage(), + I.getAddressSpace(), I.getName(), New.get()); NF->copyAttributesFrom(&I); VMap[&I] = NF; } @@ -91,8 +92,8 @@ std::unique_ptr<Module> llvm::CloneModule( GlobalValue *GV; if (I->getValueType()->isFunctionTy()) GV = Function::Create(cast<FunctionType>(I->getValueType()), - GlobalValue::ExternalLinkage, I->getName(), - New.get()); + GlobalValue::ExternalLinkage, + I->getAddressSpace(), I->getName(), New.get()); else GV = new GlobalVariable( *New, I->getValueType(), false, GlobalValue::ExternalLinkage, diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index eeb5d2bf5eb..d9f39bd1749 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -670,10 +670,9 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, AllowVarArgs && oldFunction->isVarArg()); // Create the new function - Function *newFunction = Function::Create(funcType, - GlobalValue::InternalLinkage, - oldFunction->getName() + "_" + - header->getName(), M); + Function *newFunction = Function::Create( + funcType, GlobalValue::InternalLinkage, oldFunction->getAddressSpace(), + oldFunction->getName() + "_" + header->getName(), M); // If the old function is no-throw, so is the new one. if (oldFunction->doesNotThrow()) newFunction->setDoesNotThrow(); |