9 changes: 6 additions & 3 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
// Emit the function proto information.
for (const Function &F : *M) {
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
// section, visibility, gc, unnamed_addr, prefix]
// section, visibility, gc, unnamed_addr, prologuedata,
// dllstorageclass, comdat, prefixdata]
Vals.push_back(VE.getTypeID(F.getType()));
Vals.push_back(F.getCallingConv());
Vals.push_back(F.isDeclaration());
Expand All @@ -681,10 +682,12 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
Vals.push_back(getEncodedVisibility(F));
Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
Vals.push_back(F.hasUnnamedAddr());
Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1)
: 0);
Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
: 0);
Vals.push_back(getEncodedDLLStorageClass(F));
Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0);
Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1)
: 0);

unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
Expand Down
16 changes: 14 additions & 2 deletions llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,14 @@ static OrderMap orderModule(const Module &M) {
for (const GlobalAlias &A : M.aliases())
if (!isa<GlobalValue>(A.getAliasee()))
orderValue(A.getAliasee(), OM);
for (const Function &F : M)
for (const Function &F : M) {
if (F.hasPrefixData())
if (!isa<GlobalValue>(F.getPrefixData()))
orderValue(F.getPrefixData(), OM);
if (F.hasPrologueData())
if (!isa<GlobalValue>(F.getPrologueData()))
orderValue(F.getPrologueData(), OM);
}
OM.LastGlobalConstantID = OM.size();

// Initializers of GlobalValues are processed in
Expand Down Expand Up @@ -264,9 +268,12 @@ static UseListOrderStack predictUseListOrder(const Module &M) {
predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
for (const GlobalAlias &A : M.aliases())
predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
for (const Function &F : M)
for (const Function &F : M) {
if (F.hasPrefixData())
predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack);
if (F.hasPrologueData())
predictValueUseListOrder(F.getPrologueData(), nullptr, OM, Stack);
}

return Stack;
}
Expand Down Expand Up @@ -314,6 +321,11 @@ ValueEnumerator::ValueEnumerator(const Module &M) {
if (I->hasPrefixData())
EnumerateValue(I->getPrefixData());

// Enumerate the prologue data constants.
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasPrologueData())
EnumerateValue(I->getPrologueData());

// Insert constants and metadata that are named at module level into the slot
// pool so that the module symbol table can refer to them...
EnumerateValueSymbolTable(M.getValueSymbolTable());
Expand Down
10 changes: 7 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ void AsmPrinter::EmitFunctionHeader() {
OutStreamer.GetCommentOS() << '\n';
}

// Emit the prefix data.
if (F->hasPrefixData())
EmitGlobalConstant(F->getPrefixData());

// Emit the CurrentFnSym. This is a virtual function to allow targets to
// do their wild and crazy things as required.
EmitFunctionEntryLabel();
Expand All @@ -528,9 +532,9 @@ void AsmPrinter::EmitFunctionHeader() {
HI.Handler->beginFunction(MF);
}

// Emit the prefix data.
if (F->hasPrefixData())
EmitGlobalConstant(F->getPrefixData());
// Emit the prologue data.
if (F->hasPrologueData())
EmitGlobalConstant(F->getPrologueData());
}

/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ static OrderMap orderModule(const Module *M) {
if (F.hasPrefixData())
if (!isa<GlobalValue>(F.getPrefixData()))
orderValue(F.getPrefixData(), OM);

if (F.hasPrologueData())
if (!isa<GlobalValue>(F.getPrologueData()))
orderValue(F.getPrologueData(), OM);

orderValue(&F, OM);

if (F.isDeclaration())
Expand Down Expand Up @@ -1902,6 +1907,11 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << " prefix ";
writeOperand(F->getPrefixData(), true);
}
if (F->hasPrologueData()) {
Out << " prologue ";
writeOperand(F->getPrologueData(), true);
}

if (F->isDeclaration()) {
Out << '\n';
} else {
Expand Down
42 changes: 38 additions & 4 deletions llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void Function::BuildLazyArguments() const {

// Clear the lazy arguments bit.
unsigned SDC = getSubclassDataFromValue();
const_cast<Function*>(this)->setValueSubclassData(SDC &= ~1);
const_cast<Function*>(this)->setValueSubclassData(SDC &= ~(1<<0));
}

size_t Function::arg_size() const {
Expand Down Expand Up @@ -335,8 +335,9 @@ void Function::dropAllReferences() {
while (!BasicBlocks.empty())
BasicBlocks.begin()->eraseFromParent();

// Prefix data is stored in a side table.
// Prefix and prologue data are stored in a side table.
setPrefixData(nullptr);
setPrologueData(nullptr);
}

void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {
Expand Down Expand Up @@ -416,6 +417,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) {
setPrefixData(SrcF->getPrefixData());
else
setPrefixData(nullptr);
if (SrcF->hasPrologueData())
setPrologueData(SrcF->getPrologueData());
else
setPrologueData(nullptr);
}

/// getIntrinsicID - This method returns the ID number of the specified
Expand Down Expand Up @@ -880,11 +885,40 @@ void Function::setPrefixData(Constant *PrefixData) {
PDHolder->setOperand(0, PrefixData);
else
PDHolder = ReturnInst::Create(getContext(), PrefixData);
SCData |= 2;
SCData |= (1<<1);
} else {
delete PDHolder;
PDMap.erase(this);
SCData &= ~2;
SCData &= ~(1<<1);
}
setValueSubclassData(SCData);
}

Constant *Function::getPrologueData() const {
assert(hasPrologueData());
const LLVMContextImpl::PrologueDataMapTy &SOMap =
getContext().pImpl->PrologueDataMap;
assert(SOMap.find(this) != SOMap.end());
return cast<Constant>(SOMap.find(this)->second->getReturnValue());
}

void Function::setPrologueData(Constant *PrologueData) {
if (!PrologueData && !hasPrologueData())
return;

unsigned PDData = getSubclassDataFromValue();
LLVMContextImpl::PrologueDataMapTy &PDMap = getContext().pImpl->PrologueDataMap;
ReturnInst *&PDHolder = PDMap[this];
if (PrologueData) {
if (PDHolder)
PDHolder->setOperand(0, PrologueData);
else
PDHolder = ReturnInst::Create(getContext(), PrologueData);
PDData |= (1<<2);
} else {
delete PDHolder;
PDMap.erase(this);
PDData &= ~(1<<2);
}
setValueSubclassData(PDData);
}
6 changes: 6 additions & 0 deletions llvm/lib/IR/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ class LLVMContextImpl {
typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;
PrefixDataMapTy PrefixDataMap;

/// \brief Mapping from a function to its prologue data, which is stored as
/// the operand of an unparented ReturnInst so that the prologue data has a
/// Use.
typedef DenseMap<const Function *, ReturnInst *> PrologueDataMapTy;
PrologueDataMapTy PrologueDataMap;

int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/IR/TypeFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ void TypeFinder::run(const Module &M, bool onlyNamed) {
if (FI->hasPrefixData())
incorporateValue(FI->getPrefixData());

if (FI->hasPrologueData())
incorporateValue(FI->getPrologueData());

// First incorporate the arguments.
for (Function::const_arg_iterator AI = FI->arg_begin(),
AE = FI->arg_end(); AI != AE; ++AI)
Expand Down
11 changes: 8 additions & 3 deletions llvm/lib/Linker/LinkModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1505,11 +1505,16 @@ bool ModuleLinker::run() {
if (DoNotLinkFromSource.count(SF)) continue;

Function *DF = cast<Function>(ValueMap[SF]);
if (SF->hasPrefixData()) {
// Link in the prefix data.

// Link in the prefix data.
if (SF->hasPrefixData())
DF->setPrefixData(MapValue(
SF->getPrefixData(), ValueMap, RF_None, &TypeMap, &ValMaterializer));
}

// Link in the prologue data.
if (SF->hasPrologueData())
DF->setPrologueData(MapValue(
SF->getPrologueData(), ValueMap, RF_None, &TypeMap, &ValMaterializer));

// Materialize if needed.
if (std::error_code EC = SF->materialize())
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Transforms/IPO/GlobalDCE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
if (F->hasPrefixData())
MarkUsedGlobalsAsNeeded(F->getPrefixData());

if (F->hasPrologueData())
MarkUsedGlobalsAsNeeded(F->getPrologueData());

for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U)
Expand Down
9 changes: 5 additions & 4 deletions llvm/test/CodeGen/X86/prefixdata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

@i = linkonce_odr global i32 1

; CHECK: f:
; CHECK-NEXT: .cfi_startproc
; CHECK: .type f,@function
; CHECK-NEXT: .long 1
; CHECK-NEXT: # 0x1
; CHECK-NEXT: f:
define void @f() prefix i32 1 {
ret void
}

; CHECK: g:
; CHECK-NEXT: .cfi_startproc
; CHECK: .type g,@function
; CHECK-NEXT: .quad i
; CHECK-NEXT: g:
define void @g() prefix i32* @i {
ret void
}
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/X86/prologuedata.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s

@i = linkonce_odr global i32 1

; CHECK: f:
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: .long 1
define void @f() prologue i32 1 {
ret void
}

; CHECK: g:
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: .quad i
define void @g() prologue i32* @i {
ret void
}
18 changes: 18 additions & 0 deletions llvm/test/Feature/prologuedata.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; RUN: llvm-as < %s | llvm-dis > %t1.ll
; RUN: FileCheck %s < %t1.ll
; RUN: llvm-as < %t1.ll | llvm-dis > %t2.ll
; RUN: diff %t1.ll %t2.ll
; RUN: opt -O3 -S < %t1.ll | FileCheck %s

; CHECK: @i
@i = linkonce_odr global i32 1

; CHECK: f(){{.*}}prologue i32 1
define void @f() prologue i32 1 {
ret void
}

; CHECK: g(){{.*}}prologue i32* @i
define void @g() prologue i32* @i {
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

@i = linkonce_odr global i32 1

; CHECK: define void @f() prefix i32* @i
define void @f() prefix i32* @i {
; CHECK: define void @f() prologue i32* @i
define void @f() prologue i32* @i {
ret void
}
10 changes: 8 additions & 2 deletions llvm/tools/verify-uselistorder/verify-uselistorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,12 @@ ValueMapping::ValueMapping(const Module &M) {
map(G.getInitializer());
for (const GlobalAlias &A : M.aliases())
map(A.getAliasee());
for (const Function &F : M)
for (const Function &F : M) {
if (F.hasPrefixData())
map(F.getPrefixData());
if (F.hasPrologueData())
map(F.getPrologueData());
}

// Function bodies.
for (const Function &F : M) {
Expand Down Expand Up @@ -463,9 +466,12 @@ static void changeUseLists(Module &M, Changer changeValueUseList) {
changeValueUseList(G.getInitializer());
for (GlobalAlias &A : M.aliases())
changeValueUseList(A.getAliasee());
for (Function &F : M)
for (Function &F : M) {
if (F.hasPrefixData())
changeValueUseList(F.getPrefixData());
if (F.hasPrologueData())
changeValueUseList(F.getPrologueData());
}

// Function bodies.
for (Function &F : M) {
Expand Down