MODULE_CODE_FUNCTION Record
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc]``
+``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix]``
The ``FUNCTION`` record (code 8) marks the declaration or definition of a
function. The operand fields are:
* *unnamed_addr*: If present and non-zero, indicates that the function has
``unnamed_addr``
+* *prefix*: If non-zero, the value index of the prefix data for this function,
+ plus 1.
+
MODULE_CODE_ALIAS Record
^^^^^^^^^^^^^^^^^^^^^^^^
name, a (possibly empty) argument list (each with optional :ref:`parameter
attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,
an optional section, an optional alignment, an optional :ref:`garbage
-collector name <gc>`, an opening curly brace, a list of basic blocks,
-and a closing curly brace.
+collector name <gc>`, an optional :ref:`prefix <prefixdata>`, an opening
+curly brace, a list of basic blocks, and a closing curly brace.
LLVM function declarations consist of the "``declare``" keyword, an
optional :ref:`linkage type <linkage>`, an optional :ref:`visibility
style <visibility>`, an optional :ref:`calling convention <callingconv>`,
an optional ``unnamed_addr`` attribute, a return type, an optional
:ref:`parameter attribute <paramattrs>` for the return type, a function
-name, a possibly empty list of arguments, an optional alignment, and an
-optional :ref:`garbage collector name <gc>`.
+name, a possibly empty list of arguments, an optional alignment, an optional
+:ref:`garbage collector name <gc>` and an optional :ref:`prefix <prefixdata>`.
A function definition contains a list of basic blocks, forming the CFG
(Control Flow Graph) for the function. Each basic block may optionally
[cconv] [ret attrs]
<ResultType> @<FunctionName> ([argument list])
[fn Attrs] [section "name"] [align N]
- [gc] { ... }
+ [gc] [prefix Constant] { ... }
.. _langref_aliases:
collector which will cause the compiler to alter its output in order to
support the named garbage collection algorithm.
+.. _prefixdata:
+
+Prefix Data
+-----------
+
+Prefix data is data associated with a function which the code generator
+will emit immediately before the function body. The purpose of this feature
+is to allow frontends to associate language-specific runtime metadata with
+specific functions and make it available through the function pointer while
+still allowing the function pointer to be called. To access the data for a
+given function, a program may bitcast the function pointer to a pointer to
+the constant's type. This implies that the IR symbol points to the start
+of the prefix data.
+
+To maintain the semantics of ordinary function calls, the prefix data must
+have a particular format. Specifically, it must begin with a sequence of
+bytes which decode to a sequence of machine instructions, valid for the
+module's target, which transfer control to the point immediately succeeding
+the prefix data, without performing any other visible action. This allows
+the inliner and other passes to reason about the semantics of the function
+definition without needing to reason about the prefix data. Obviously this
+makes the format of the prefix data highly target dependent.
+
+A trivial example of valid prefix data for the x86 architecture is ``i8 144``,
+which encodes the ``nop`` instruction:
+
+.. code-block:: llvm
+
+ define void @f() prefix i8 144 { ... }
+
+Generally prefix data can be formed by encoding a relative branch instruction
+which skips the metadata, as in this example of valid prefix data for the
+x86_64 architecture, where the first two bytes encode ``jmp .+10``:
+
+.. code-block:: llvm
+
+ %0 = type <{ i8, i8, i8* }>
+
+ define void @f() prefix %0 <{ i8 235, i8 8, i8* @md}> { ... }
+
+A function may have prefix data but no body. This has similar semantics
+to the ``available_externally`` linkage in that the data may be used by the
+optimizers but will not be emitted in the object file.
+
.. _attrgrp:
Attribute Groups
/// calling convention of this function. The enum values for the known
/// calling conventions are defined in CallingConv.h.
CallingConv::ID getCallingConv() const {
- return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1);
+ return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 2);
}
void setCallingConv(CallingConv::ID CC) {
- setValueSubclassData((getSubclassDataFromValue() & 1) |
- (static_cast<unsigned>(CC) << 1));
+ setValueSubclassData((getSubclassDataFromValue() & 3) |
+ (static_cast<unsigned>(CC) << 2));
}
/// @brief Return the attribute list for this Function.
size_t arg_size() const;
bool arg_empty() const;
+ bool hasPrefixData() const {
+ return getSubclassDataFromValue() & 2;
+ }
+
+ Constant *getPrefixData() const;
+ void setPrefixData(Constant *PrefixData);
+
/// viewCFG - This function is meant for use from the debugger. You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function with the code for each
KEYWORD(alignstack);
KEYWORD(inteldialect);
KEYWORD(gc);
+ KEYWORD(prefix);
KEYWORD(ccc);
KEYWORD(fastcc);
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
/// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
-/// OptionalAlign OptGC
+/// OptionalAlign OptGC OptionalPrefix
bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
// Parse the linkage.
LocTy LinkageLoc = Lex.getLoc();
std::string GC;
bool UnnamedAddr;
LocTy UnnamedAddrLoc;
+ Constant *Prefix = 0;
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
ParseStringConstant(Section)) ||
ParseOptionalAlignment(Alignment) ||
(EatIfPresent(lltok::kw_gc) &&
- ParseStringConstant(GC)))
+ ParseStringConstant(GC)) ||
+ (EatIfPresent(lltok::kw_prefix) &&
+ ParseGlobalTypeAndValue(Prefix)))
return true;
if (FuncAttrs.contains(Attribute::Builtin))
Fn->setAlignment(Alignment);
Fn->setSection(Section);
if (!GC.empty()) Fn->setGC(GC.c_str());
+ Fn->setPrefixData(Prefix);
ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;
// Add all of the arguments we parsed to the function.
kw_alignstack,
kw_inteldialect,
kw_gc,
+ kw_prefix,
kw_c,
kw_cc, kw_ccc, kw_fastcc, kw_coldcc,
bool BitcodeReader::ResolveGlobalAndAliasInits() {
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist;
GlobalInitWorklist.swap(GlobalInits);
AliasInitWorklist.swap(AliasInits);
+ FunctionPrefixWorklist.swap(FunctionPrefixes);
while (!GlobalInitWorklist.empty()) {
unsigned ValID = GlobalInitWorklist.back().second;
}
AliasInitWorklist.pop_back();
}
+
+ while (!FunctionPrefixWorklist.empty()) {
+ unsigned ValID = FunctionPrefixWorklist.back().second;
+ if (ValID >= ValueList.size()) {
+ FunctionPrefixes.push_back(FunctionPrefixWorklist.back());
+ } else {
+ if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
+ FunctionPrefixWorklist.back().first->setPrefixData(C);
+ else
+ return Error("Function prefix is not a constant!");
+ }
+ FunctionPrefixWorklist.pop_back();
+ }
+
return false;
}
if (Record.size() > 9)
UnnamedAddr = Record[9];
Func->setUnnamedAddr(UnnamedAddr);
+ if (Record.size() > 10 && Record[10] != 0)
+ FunctionPrefixes.push_back(std::make_pair(Func, Record[10]-1));
ValueList.push_back(Func);
// If this is a function with a body, remember the prototype we are
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+ std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
/// MAttributes - The set of attributes by index. Index zero in the
/// file is for null, and is thus not represented here. As such all indices
// Emit the function proto information.
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {
// FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
- // section, visibility, gc, unnamed_addr]
+ // section, visibility, gc, unnamed_addr, prefix]
Vals.push_back(VE.getTypeID(F->getType()));
Vals.push_back(F->getCallingConv());
Vals.push_back(F->isDeclaration());
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);
unsigned AbbrevToUse = 0;
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
WriteUseList(FI, VE, Stream);
if (!FI->isDeclaration())
WriteFunctionUseList(FI, VE, Stream);
+ if (FI->hasPrefixData())
+ WriteUseList(FI->getPrefixData(), VE, Stream);
}
// Write the aliases.
I != E; ++I)
EnumerateValue(I->getAliasee());
+ // Enumerate the prefix data constants.
+ for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
+ if (I->hasPrefixData())
+ EnumerateValue(I->getPrefixData());
+
// 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());
OutStreamer.EmitLabel(DeadBlockSyms[i]);
}
+ // Emit the prefix data.
+ if (F->hasPrefixData())
+ EmitGlobalConstant(F->getPrefixData());
+
// Emit pre-function debug and/or EH information.
if (DE) {
NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
Out << " align " << F->getAlignment();
if (F->hasGC())
Out << " gc \"" << F->getGC() << '"';
+ if (F->hasPrefixData()) {
+ Out << " prefix ";
+ writeOperand(F->getPrefixData(), true);
+ }
if (F->isDeclaration()) {
Out << '\n';
} else {
// blockaddresses, but BasicBlock's destructor takes care of those.
while (!BasicBlocks.empty())
BasicBlocks.begin()->eraseFromParent();
+
+ // Prefix data is stored in a side table.
+ setPrefixData(0);
}
void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {
setGC(SrcF->getGC());
else
clearGC();
+ if (SrcF->hasPrefixData())
+ setPrefixData(SrcF->getPrefixData());
+ else
+ setPrefixData(0);
}
/// getIntrinsicID - This method returns the ID number of the specified
return false;
}
+
+Constant *Function::getPrefixData() const {
+ assert(hasPrefixData());
+ const LLVMContextImpl::PrefixDataMapTy &PDMap =
+ getContext().pImpl->PrefixDataMap;
+ assert(PDMap.find(this) != PDMap.end());
+ return cast<Constant>(PDMap.find(this)->second->getReturnValue());
+}
+
+void Function::setPrefixData(Constant *PrefixData) {
+ if (!PrefixData && !hasPrefixData())
+ return;
+
+ unsigned SCData = getSubclassDataFromValue();
+ LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap;
+ ReturnInst *&PDHolder = PDMap[this];
+ if (PrefixData) {
+ if (PDHolder)
+ PDHolder->setOperand(0, PrefixData);
+ else
+ PDHolder = ReturnInst::Create(getContext(), PrefixData);
+ SCData |= 2;
+ } else {
+ delete PDHolder;
+ PDMap.erase(this);
+ SCData &= ~2;
+ }
+ setValueSubclassData(SCData);
+}
typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy;
IntrinsicIDCacheTy IntrinsicIDCache;
+ /// \brief Mapping from a function to its prefix data, which is stored as the
+ /// operand of an unparented ReturnInst so that the prefix data has a Use.
+ typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;
+ PrefixDataMapTy PrefixDataMap;
+
int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
incorporateType(FI->getType());
+ if (FI->hasPrefixData())
+ incorporateValue(FI->getPrefixData());
+
// First incorporate the arguments.
for (Function::const_arg_iterator AI = FI->arg_begin(),
AE = FI->arg_end(); AI != AE; ++AI)
// Skip if not linking from source.
if (DoNotLinkFromSource.count(SF)) continue;
+ Function *DF = cast<Function>(ValueMap[SF]);
+ if (SF->hasPrefixData()) {
+ // Link in the prefix data.
+ DF->setPrefixData(MapValue(
+ SF->getPrefixData(), ValueMap, RF_None, &TypeMap, &ValMaterializer));
+ }
+
// Skip if no body (function is external) or materialize.
if (SF->isDeclaration()) {
if (!SF->isMaterializable())
return true;
}
- linkFunctionBody(cast<Function>(ValueMap[SF]), SF);
+ linkFunctionBody(DF, SF);
SF->Dematerialize();
}
continue;
Function *DF = cast<Function>(ValueMap[SF]);
+ if (SF->hasPrefixData()) {
+ // Link in the prefix data.
+ DF->setPrefixData(MapValue(SF->getPrefixData(),
+ ValueMap,
+ RF_None,
+ &TypeMap,
+ &ValMaterializer));
+ }
// Materialize if necessary.
if (SF->isDeclaration()) {
// any globals used will be marked as needed.
Function *F = cast<Function>(G);
+ if (F->hasPrefixData())
+ MarkUsedGlobalsAsNeeded(F->getPrefixData());
+
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)
--- /dev/null
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+
+@i = linkonce_odr global i32 1
+
+; CHECK: f:
+; CHECK-NEXT: .long 1
+define void @f() prefix i32 1 {
+ ret void
+}
+
+; CHECK: g:
+; CHECK-NEXT: .quad i
+define void @g() prefix i32* @i {
+ ret void
+}
--- /dev/null
+; 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(){{.*}}prefix i32 1
+define void @f() prefix i32 1 {
+ ret void
+}
+
+; CHECK: g(){{.*}}prefix i32* @i
+define void @g() prefix i32* @i {
+ ret void
+}
--- /dev/null
+; RUN: echo > %t.ll
+; RUN: llvm-link %t.ll %s -S -o - | FileCheck %s
+
+@i = linkonce_odr global i32 1
+
+; CHECK: define void @f() prefix i32* @i
+define void @f() prefix i32* @i {
+ ret void
+}