summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp127
-rw-r--r--llvm/lib/AsmParser/LLParser.h14
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp10
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp4
-rw-r--r--llvm/lib/IR/AsmWriter.cpp30
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp4
-rw-r--r--llvm/lib/IR/Function.cpp20
-rw-r--r--llvm/lib/IR/Globals.cpp5
-rw-r--r--llvm/lib/IR/Module.cpp8
-rw-r--r--llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp7
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp4
-rw-r--r--llvm/lib/Transforms/Utils/CloneModule.cpp9
-rw-r--r--llvm/lib/Transforms/Utils/CodeExtractor.cpp7
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();
OpenPOWER on IntegriCloud