<div dir="ltr"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+A trivial example of valid prefix data for the x86 architecture is ``i8 144``,</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+which encodes the ``nop`` instruction:</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+.. code-block:: llvm</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+    define void @f() prefix i8 144 { ... }</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+Generally prefix data can be formed by encoding a relative branch instruction</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+which skips the metadata, as in this example of valid prefix data for the</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+x86_64 architecture, where the first two bytes encode ``jmp .+10``:</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+.. code-block:: llvm</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+    %0 = type <{ i8, i8, i8* }></span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+    define void @f() prefix %0 <{ i8 235, i8 8, i8* @md}> { ... }</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+A function may have prefix data but no body.  This has similar semantics</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+to the ``available_externally`` linkage in that the data may be used by the</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">
<span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+optimizers but will not be emitted in the object file.</span><br style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">+</span><br>
<div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">Can you be a bit more explicit about the endianness/layout of the emitted data?</span></div>
<div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">-- Sean Silva</span></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Sun, Sep 15, 2013 at 9:08 PM, Peter Collingbourne <span dir="ltr"><<a href="mailto:peter@pcc.me.uk" target="_blank">peter@pcc.me.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: pcc<br>
Date: Sun Sep 15 20:08:15 2013<br>
New Revision: 190773<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=190773&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=190773&view=rev</a><br>
Log:<br>
Implement function prefix data as an IR feature.<br>
<br>
Previous discussion:<br>
<a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/063909.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/063909.html</a><br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D1191" target="_blank">http://llvm-reviews.chandlerc.com/D1191</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/prefixdata.ll<br>
    llvm/trunk/test/Feature/prefixdata.ll<br>
    llvm/trunk/test/Linker/prefixdata.ll<br>
Modified:<br>
    llvm/trunk/docs/BitCodeFormat.rst<br>
    llvm/trunk/docs/LangRef.rst<br>
    llvm/trunk/include/llvm/IR/Function.h<br>
    llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
    llvm/trunk/lib/AsmParser/LLParser.cpp<br>
    llvm/trunk/lib/AsmParser/LLToken.h<br>
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h<br>
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
    llvm/trunk/lib/IR/AsmWriter.cpp<br>
    llvm/trunk/lib/IR/Function.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.h<br>
    llvm/trunk/lib/IR/TypeFinder.cpp<br>
    llvm/trunk/lib/Linker/LinkModules.cpp<br>
    llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp<br>
<br>
Modified: llvm/trunk/docs/BitCodeFormat.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.rst?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/BitCodeFormat.rst?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/docs/BitCodeFormat.rst (original)<br>
+++ llvm/trunk/docs/BitCodeFormat.rst Sun Sep 15 20:08:15 2013<br>
@@ -718,7 +718,7 @@ global variable. The operand fields are:<br>
 MODULE_CODE_FUNCTION Record<br>
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
<br>
-``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc]``<br>
+``[FUNCTION, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prefix]``<br>
<br>
 The ``FUNCTION`` record (code 8) marks the declaration or definition of a<br>
 function. The operand fields are:<br>
@@ -757,6 +757,9 @@ function. The operand fields are:<br>
 * *unnamed_addr*: If present and non-zero, indicates that the function has<br>
   ``unnamed_addr``<br>
<br>
+* *prefix*: If non-zero, the value index of the prefix data for this function,<br>
+  plus 1.<br>
+<br>
 MODULE_CODE_ALIAS Record<br>
 ^^^^^^^^^^^^^^^^^^^^^^^^<br>
<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Sun Sep 15 20:08:15 2013<br>
@@ -552,16 +552,16 @@ an optional ``unnamed_addr`` attribute,<br>
 name, a (possibly empty) argument list (each with optional :ref:`parameter<br>
 attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,<br>
 an optional section, an optional alignment, an optional :ref:`garbage<br>
-collector name <gc>`, an opening curly brace, a list of basic blocks,<br>
-and a closing curly brace.<br>
+collector name <gc>`, an optional :ref:`prefix <prefixdata>`, an opening<br>
+curly brace, a list of basic blocks, and a closing curly brace.<br>
<br>
 LLVM function declarations consist of the "``declare``" keyword, an<br>
 optional :ref:`linkage type <linkage>`, an optional :ref:`visibility<br>
 style <visibility>`, an optional :ref:`calling convention <callingconv>`,<br>
 an optional ``unnamed_addr`` attribute, a return type, an optional<br>
 :ref:`parameter attribute <paramattrs>` for the return type, a function<br>
-name, a possibly empty list of arguments, an optional alignment, and an<br>
-optional :ref:`garbage collector name <gc>`.<br>
+name, a possibly empty list of arguments, an optional alignment, an optional<br>
+:ref:`garbage collector name <gc>` and an optional :ref:`prefix <prefixdata>`.<br>
<br>
 A function definition contains a list of basic blocks, forming the CFG<br>
 (Control Flow Graph) for the function. Each basic block may optionally<br>
@@ -598,7 +598,7 @@ Syntax::<br>
            [cconv] [ret attrs]<br>
            <ResultType> @<FunctionName> ([argument list])<br>
            [fn Attrs] [section "name"] [align N]<br>
-           [gc] { ... }<br>
+           [gc] [prefix Constant] { ... }<br>
<br>
 .. _langref_aliases:<br>
<br>
@@ -757,6 +757,50 @@ The compiler declares the supported valu<br>
 collector which will cause the compiler to alter its output in order to<br>
 support the named garbage collection algorithm.<br>
<br>
+.. _prefixdata:<br>
+<br>
+Prefix Data<br>
+-----------<br>
+<br>
+Prefix data is data associated with a function which the code generator<br>
+will emit immediately before the function body.  The purpose of this feature<br>
+is to allow frontends to associate language-specific runtime metadata with<br>
+specific functions and make it available through the function pointer while<br>
+still allowing the function pointer to be called.  To access the data for a<br>
+given function, a program may bitcast the function pointer to a pointer to<br>
+the constant's type.  This implies that the IR symbol points to the start<br>
+of the prefix data.<br>
+<br>
+To maintain the semantics of ordinary function calls, the prefix data must<br>
+have a particular format.  Specifically, it must begin with a sequence of<br>
+bytes which decode to a sequence of machine instructions, valid for the<br>
+module's target, which transfer control to the point immediately succeeding<br>
+the prefix data, without performing any other visible action.  This allows<br>
+the inliner and other passes to reason about the semantics of the function<br>
+definition without needing to reason about the prefix data.  Obviously this<br>
+makes the format of the prefix data highly target dependent.<br>
+<br>
+A trivial example of valid prefix data for the x86 architecture is ``i8 144``,<br>
+which encodes the ``nop`` instruction:<br>
+<br>
+.. code-block:: llvm<br>
+<br>
+    define void @f() prefix i8 144 { ... }<br>
+<br>
+Generally prefix data can be formed by encoding a relative branch instruction<br>
+which skips the metadata, as in this example of valid prefix data for the<br>
+x86_64 architecture, where the first two bytes encode ``jmp .+10``:<br>
+<br>
+.. code-block:: llvm<br>
+<br>
+    %0 = type <{ i8, i8, i8* }><br>
+<br>
+    define void @f() prefix %0 <{ i8 235, i8 8, i8* @md}> { ... }<br>
+<br>
+A function may have prefix data but no body.  This has similar semantics<br>
+to the ``available_externally`` linkage in that the data may be used by the<br>
+optimizers but will not be emitted in the object file.<br>
+<br>
 .. _attrgrp:<br>
<br>
 Attribute Groups<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Function.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Function.h (original)<br>
+++ llvm/trunk/include/llvm/IR/Function.h Sun Sep 15 20:08:15 2013<br>
@@ -159,11 +159,11 @@ public:<br>
   /// calling convention of this function.  The enum values for the known<br>
   /// calling conventions are defined in CallingConv.h.<br>
   CallingConv::ID getCallingConv() const {<br>
-    return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1);<br>
+    return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 2);<br>
   }<br>
   void setCallingConv(CallingConv::ID CC) {<br>
-    setValueSubclassData((getSubclassDataFromValue() & 1) |<br>
-                         (static_cast<unsigned>(CC) << 1));<br>
+    setValueSubclassData((getSubclassDataFromValue() & 3) |<br>
+                         (static_cast<unsigned>(CC) << 2));<br>
   }<br>
<br>
   /// @brief Return the attribute list for this Function.<br>
@@ -427,6 +427,13 @@ public:<br>
   size_t arg_size() const;<br>
   bool arg_empty() const;<br>
<br>
+  bool hasPrefixData() const {<br>
+    return getSubclassDataFromValue() & 2;<br>
+  }<br>
+<br>
+  Constant *getPrefixData() const;<br>
+  void setPrefixData(Constant *PrefixData);<br>
+<br>
   /// viewCFG - This function is meant for use from the debugger.  You can just<br>
   /// say 'call F->viewCFG()' and a ghostview window should pop up from the<br>
   /// program, displaying the CFG of the current function with the code for each<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Sun Sep 15 20:08:15 2013<br>
@@ -540,6 +540,7 @@ lltok::Kind LLLexer::LexIdentifier() {<br>
   KEYWORD(alignstack);<br>
   KEYWORD(inteldialect);<br>
   KEYWORD(gc);<br>
+  KEYWORD(prefix);<br>
<br>
   KEYWORD(ccc);<br>
   KEYWORD(fastcc);<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Sun Sep 15 20:08:15 2013<br>
@@ -2922,7 +2922,7 @@ bool LLParser::ParseTypeAndBasicBlock(Ba<br>
 /// FunctionHeader<br>
 ///   ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs<br>
 ///       OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection<br>
-///       OptionalAlign OptGC<br>
+///       OptionalAlign OptGC OptionalPrefix<br>
 bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {<br>
   // Parse the linkage.<br>
   LocTy LinkageLoc = Lex.getLoc();<br>
@@ -3001,6 +3001,7 @@ bool LLParser::ParseFunctionHeader(Funct<br>
   std::string GC;<br>
   bool UnnamedAddr;<br>
   LocTy UnnamedAddrLoc;<br>
+  Constant *Prefix = 0;<br>
<br>
   if (ParseArgumentList(ArgList, isVarArg) ||<br>
       ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,<br>
@@ -3011,7 +3012,9 @@ bool LLParser::ParseFunctionHeader(Funct<br>
        ParseStringConstant(Section)) ||<br>
       ParseOptionalAlignment(Alignment) ||<br>
       (EatIfPresent(lltok::kw_gc) &&<br>
-       ParseStringConstant(GC)))<br>
+       ParseStringConstant(GC)) ||<br>
+      (EatIfPresent(lltok::kw_prefix) &&<br>
+       ParseGlobalTypeAndValue(Prefix)))<br>
     return true;<br>
<br>
   if (FuncAttrs.contains(Attribute::Builtin))<br>
@@ -3109,6 +3112,7 @@ bool LLParser::ParseFunctionHeader(Funct<br>
   Fn->setAlignment(Alignment);<br>
   Fn->setSection(Section);<br>
   if (!GC.empty()) Fn->setGC(GC.c_str());<br>
+  Fn->setPrefixData(Prefix);<br>
   ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;<br>
<br>
   // Add all of the arguments we parsed to the function.<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLToken.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLToken.h (original)<br>
+++ llvm/trunk/lib/AsmParser/LLToken.h Sun Sep 15 20:08:15 2013<br>
@@ -81,6 +81,7 @@ namespace lltok {<br>
     kw_alignstack,<br>
     kw_inteldialect,<br>
     kw_gc,<br>
+    kw_prefix,<br>
     kw_c,<br>
<br>
     kw_cc, kw_ccc, kw_fastcc, kw_coldcc,<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sun Sep 15 20:08:15 2013<br>
@@ -1106,9 +1106,11 @@ uint64_t BitcodeReader::decodeSignRotate<br>
 bool BitcodeReader::ResolveGlobalAndAliasInits() {<br>
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;<br>
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;<br>
+  std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist;<br>
<br>
   GlobalInitWorklist.swap(GlobalInits);<br>
   AliasInitWorklist.swap(AliasInits);<br>
+  FunctionPrefixWorklist.swap(FunctionPrefixes);<br>
<br>
   while (!GlobalInitWorklist.empty()) {<br>
     unsigned ValID = GlobalInitWorklist.back().second;<br>
@@ -1136,6 +1138,20 @@ bool BitcodeReader::ResolveGlobalAndAlia<br>
     }<br>
     AliasInitWorklist.pop_back();<br>
   }<br>
+<br>
+  while (!FunctionPrefixWorklist.empty()) {<br>
+    unsigned ValID = FunctionPrefixWorklist.back().second;<br>
+    if (ValID >= ValueList.size()) {<br>
+      FunctionPrefixes.push_back(FunctionPrefixWorklist.back());<br>
+    } else {<br>
+      if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))<br>
+        FunctionPrefixWorklist.back().first->setPrefixData(C);<br>
+      else<br>
+        return Error("Function prefix is not a constant!");<br>
+    }<br>
+    FunctionPrefixWorklist.pop_back();<br>
+  }<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -1881,6 +1897,8 @@ bool BitcodeReader::ParseModule(bool Res<br>
       if (Record.size() > 9)<br>
         UnnamedAddr = Record[9];<br>
       Func->setUnnamedAddr(UnnamedAddr);<br>
+      if (Record.size() > 10 && Record[10] != 0)<br>
+        FunctionPrefixes.push_back(std::make_pair(Func, Record[10]-1));<br>
       ValueList.push_back(Func);<br>
<br>
       // If this is a function with a body, remember the prototype we are<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original)<br>
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Sun Sep 15 20:08:15 2013<br>
@@ -142,6 +142,7 @@ class BitcodeReader : public GVMateriali<br>
<br>
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;<br>
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;<br>
+  std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;<br>
<br>
   /// MAttributes - The set of attributes by index.  Index zero in the<br>
   /// file is for null, and is thus not represented here.  As such all indices<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sun Sep 15 20:08:15 2013<br>
@@ -632,7 +632,7 @@ static void WriteModuleInfo(const Module<br>
   // Emit the function proto information.<br>
   for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) {<br>
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattrs, alignment,<br>
-    //             section, visibility, gc, unnamed_addr]<br>
+    //             section, visibility, gc, unnamed_addr, prefix]<br>
     Vals.push_back(VE.getTypeID(F->getType()));<br>
     Vals.push_back(F->getCallingConv());<br>
     Vals.push_back(F->isDeclaration());<br>
@@ -643,6 +643,8 @@ static void WriteModuleInfo(const Module<br>
     Vals.push_back(getEncodedVisibility(F));<br>
     Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);<br>
     Vals.push_back(F->hasUnnamedAddr());<br>
+    Vals.push_back(F->hasPrefixData() ? (VE.getValueID(F->getPrefixData()) + 1)<br>
+                                      : 0);<br>
<br>
     unsigned AbbrevToUse = 0;<br>
     Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);<br>
@@ -1863,6 +1865,8 @@ static void WriteModuleUseLists(const Mo<br>
     WriteUseList(FI, VE, Stream);<br>
     if (!FI->isDeclaration())<br>
       WriteFunctionUseList(FI, VE, Stream);<br>
+    if (FI->hasPrefixData())<br>
+      WriteUseList(FI->getPrefixData(), VE, Stream);<br>
   }<br>
<br>
   // Write the aliases.<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Sun Sep 15 20:08:15 2013<br>
@@ -60,6 +60,11 @@ ValueEnumerator::ValueEnumerator(const M<br>
        I != E; ++I)<br>
     EnumerateValue(I->getAliasee());<br>
<br>
+  // Enumerate the prefix data constants.<br>
+  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)<br>
+    if (I->hasPrefixData())<br>
+      EnumerateValue(I->getPrefixData());<br>
+<br>
   // Insert constants and metadata that are named at module level into the slot<br>
   // pool so that the module symbol table can refer to them...<br>
   EnumerateValueSymbolTable(M->getValueSymbolTable());<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sun Sep 15 20:08:15 2013<br>
@@ -459,6 +459,10 @@ void AsmPrinter::EmitFunctionHeader() {<br>
     OutStreamer.EmitLabel(DeadBlockSyms[i]);<br>
   }<br>
<br>
+  // Emit the prefix data.<br>
+  if (F->hasPrefixData())<br>
+    EmitGlobalConstant(F->getPrefixData());<br>
+<br>
   // Emit pre-function debug and/or EH information.<br>
   if (DE) {<br>
     NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);<br>
<br>
Modified: llvm/trunk/lib/IR/AsmWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)<br>
+++ llvm/trunk/lib/IR/AsmWriter.cpp Sun Sep 15 20:08:15 2013<br>
@@ -1647,6 +1647,10 @@ void AssemblyWriter::printFunction(const<br>
     Out << " align " << F->getAlignment();<br>
   if (F->hasGC())<br>
     Out << " gc \"" << F->getGC() << '"';<br>
+  if (F->hasPrefixData()) {<br>
+    Out << " prefix ";<br>
+    writeOperand(F->getPrefixData(), true);<br>
+  }<br>
   if (F->isDeclaration()) {<br>
     Out << '\n';<br>
   } else {<br>
<br>
Modified: llvm/trunk/lib/IR/Function.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/IR/Function.cpp (original)<br>
+++ llvm/trunk/lib/IR/Function.cpp Sun Sep 15 20:08:15 2013<br>
@@ -276,6 +276,9 @@ void Function::dropAllReferences() {<br>
   // blockaddresses, but BasicBlock's destructor takes care of those.<br>
   while (!BasicBlocks.empty())<br>
     BasicBlocks.begin()->eraseFromParent();<br>
+<br>
+  // Prefix data is stored in a side table.<br>
+  setPrefixData(0);<br>
 }<br>
<br>
 void Function::addAttribute(unsigned i, Attribute::AttrKind attr) {<br>
@@ -351,6 +354,10 @@ void Function::copyAttributesFrom(const<br>
     setGC(SrcF->getGC());<br>
   else<br>
     clearGC();<br>
+  if (SrcF->hasPrefixData())<br>
+    setPrefixData(SrcF->getPrefixData());<br>
+  else<br>
+    setPrefixData(0);<br>
 }<br>
<br>
 /// getIntrinsicID - This method returns the ID number of the specified<br>
@@ -720,3 +727,32 @@ bool Function::callsFunctionThatReturnsT<br>
<br>
   return false;<br>
 }<br>
+<br>
+Constant *Function::getPrefixData() const {<br>
+  assert(hasPrefixData());<br>
+  const LLVMContextImpl::PrefixDataMapTy &PDMap =<br>
+      getContext().pImpl->PrefixDataMap;<br>
+  assert(PDMap.find(this) != PDMap.end());<br>
+  return cast<Constant>(PDMap.find(this)->second->getReturnValue());<br>
+}<br>
+<br>
+void Function::setPrefixData(Constant *PrefixData) {<br>
+  if (!PrefixData && !hasPrefixData())<br>
+    return;<br>
+<br>
+  unsigned SCData = getSubclassDataFromValue();<br>
+  LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap;<br>
+  ReturnInst *&PDHolder = PDMap[this];<br>
+  if (PrefixData) {<br>
+    if (PDHolder)<br>
+      PDHolder->setOperand(0, PrefixData);<br>
+    else<br>
+      PDHolder = ReturnInst::Create(getContext(), PrefixData);<br>
+    SCData |= 2;<br>
+  } else {<br>
+    delete PDHolder;<br>
+    PDMap.erase(this);<br>
+    SCData &= ~2;<br>
+  }<br>
+  setValueSubclassData(SCData);<br>
+}<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Sun Sep 15 20:08:15 2013<br>
@@ -355,6 +355,11 @@ public:<br>
   typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy;<br>
   IntrinsicIDCacheTy IntrinsicIDCache;<br>
<br>
+  /// \brief Mapping from a function to its prefix data, which is stored as the<br>
+  /// operand of an unparented ReturnInst so that the prefix data has a Use.<br>
+  typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;<br>
+  PrefixDataMapTy PrefixDataMap;<br>
+<br>
   int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);<br>
   int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/TypeFinder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/TypeFinder.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/TypeFinder.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/IR/TypeFinder.cpp (original)<br>
+++ llvm/trunk/lib/IR/TypeFinder.cpp Sun Sep 15 20:08:15 2013<br>
@@ -44,6 +44,9 @@ void TypeFinder::run(const Module &M, bo<br>
   for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {<br>
     incorporateType(FI->getType());<br>
<br>
+    if (FI->hasPrefixData())<br>
+      incorporateValue(FI->getPrefixData());<br>
+<br>
     // First incorporate the arguments.<br>
     for (Function::const_arg_iterator AI = FI->arg_begin(),<br>
            AE = FI->arg_end(); AI != AE; ++AI)<br>
<br>
Modified: llvm/trunk/lib/Linker/LinkModules.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)<br>
+++ llvm/trunk/lib/Linker/LinkModules.cpp Sun Sep 15 20:08:15 2013<br>
@@ -1260,6 +1260,13 @@ bool ModuleLinker::run() {<br>
     // Skip if not linking from source.<br>
     if (DoNotLinkFromSource.count(SF)) continue;<br>
<br>
+    Function *DF = cast<Function>(ValueMap[SF]);<br>
+    if (SF->hasPrefixData()) {<br>
+      // Link in the prefix data.<br>
+      DF->setPrefixData(MapValue(<br>
+          SF->getPrefixData(), ValueMap, RF_None, &TypeMap, &ValMaterializer));<br>
+    }<br>
+<br>
     // Skip if no body (function is external) or materialize.<br>
     if (SF->isDeclaration()) {<br>
       if (!SF->isMaterializable())<br>
@@ -1268,7 +1275,7 @@ bool ModuleLinker::run() {<br>
         return true;<br>
     }<br>
<br>
-    linkFunctionBody(cast<Function>(ValueMap[SF]), SF);<br>
+    linkFunctionBody(DF, SF);<br>
     SF->Dematerialize();<br>
   }<br>
<br>
@@ -1296,6 +1303,14 @@ bool ModuleLinker::run() {<br>
         continue;<br>
<br>
       Function *DF = cast<Function>(ValueMap[SF]);<br>
+      if (SF->hasPrefixData()) {<br>
+        // Link in the prefix data.<br>
+        DF->setPrefixData(MapValue(SF->getPrefixData(),<br>
+                                   ValueMap,<br>
+                                   RF_None,<br>
+                                   &TypeMap,<br>
+                                   &ValMaterializer));<br>
+      }<br>
<br>
       // Materialize if necessary.<br>
       if (SF->isDeclaration()) {<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp?rev=190773&r1=190772&r2=190773&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp?rev=190773&r1=190772&r2=190773&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Sun Sep 15 20:08:15 2013<br>
@@ -179,6 +179,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalVal<br>
     // any globals used will be marked as needed.<br>
     Function *F = cast<Function>(G);<br>
<br>
+    if (F->hasPrefixData())<br>
+      MarkUsedGlobalsAsNeeded(F->getPrefixData());<br>
+<br>
     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)<br>
       for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)<br>
         for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U)<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/prefixdata.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/prefixdata.ll?rev=190773&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/prefixdata.ll?rev=190773&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/prefixdata.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/prefixdata.ll Sun Sep 15 20:08:15 2013<br>
@@ -0,0 +1,15 @@<br>
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s<br>
+<br>
+@i = linkonce_odr global i32 1<br>
+<br>
+; CHECK: f:<br>
+; CHECK-NEXT: .long    1<br>
+define void @f() prefix i32 1 {<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK: g:<br>
+; CHECK-NEXT: .quad    i<br>
+define void @g() prefix i32* @i {<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/Feature/prefixdata.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/prefixdata.ll?rev=190773&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/prefixdata.ll?rev=190773&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/Feature/prefixdata.ll (added)<br>
+++ llvm/trunk/test/Feature/prefixdata.ll Sun Sep 15 20:08:15 2013<br>
@@ -0,0 +1,18 @@<br>
+; RUN: llvm-as < %s | llvm-dis > %t1.ll<br>
+; RUN: FileCheck %s < %t1.ll<br>
+; RUN: llvm-as < %t1.ll | llvm-dis > %t2.ll<br>
+; RUN: diff %t1.ll %t2.ll<br>
+; RUN: opt -O3 -S < %t1.ll | FileCheck %s<br>
+<br>
+; CHECK: @i<br>
+@i = linkonce_odr global i32 1<br>
+<br>
+; CHECK: f(){{.*}}prefix i32 1<br>
+define void @f() prefix i32 1 {<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK: g(){{.*}}prefix i32* @i<br>
+define void @g() prefix i32* @i {<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/Linker/prefixdata.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/prefixdata.ll?rev=190773&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/prefixdata.ll?rev=190773&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/Linker/prefixdata.ll (added)<br>
+++ llvm/trunk/test/Linker/prefixdata.ll Sun Sep 15 20:08:15 2013<br>
@@ -0,0 +1,9 @@<br>
+; RUN: echo > %t.ll<br>
+; RUN: llvm-link %t.ll %s -S -o - | FileCheck %s<br>
+<br>
+@i = linkonce_odr global i32 1<br>
+<br>
+; CHECK: define void @f() prefix i32* @i<br>
+define void @f() prefix i32* @i {<br>
+  ret void<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>