<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
p.Code, li.Code, div.Code
{mso-style-name:Code;
mso-style-link:"Code Char";
margin:0in;
margin-bottom:.0001pt;
mso-add-space:auto;
font-size:9.0pt;
font-family:"Courier New";}
p.CodeCxSpFirst, li.CodeCxSpFirst, div.CodeCxSpFirst
{mso-style-name:CodeCxSpFirst;
mso-style-link:"Code Char";
mso-style-type:export-only;
margin:0in;
margin-bottom:.0001pt;
mso-add-space:auto;
font-size:9.0pt;
font-family:"Courier New";}
p.CodeCxSpMiddle, li.CodeCxSpMiddle, div.CodeCxSpMiddle
{mso-style-name:CodeCxSpMiddle;
mso-style-link:"Code Char";
mso-style-type:export-only;
margin:0in;
margin-bottom:.0001pt;
mso-add-space:auto;
font-size:9.0pt;
font-family:"Courier New";}
p.CodeCxSpLast, li.CodeCxSpLast, div.CodeCxSpLast
{mso-style-name:CodeCxSpLast;
mso-style-link:"Code Char";
mso-style-type:export-only;
margin:0in;
margin-bottom:.0001pt;
mso-add-space:auto;
font-size:9.0pt;
font-family:"Courier New";}
span.CodeChar
{mso-style-name:"Code Char";
mso-style-link:Code;
font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle20
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:12.0pt">I have a question about the following code in TypeMapper::addTypeMapping in IRMover.cpp:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">if (!areTypesIsomorphic(DstTy, SrcTy)) {
<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> :<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> :<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">} else {
<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // SrcTy and DstTy are recursively ismorphic. We clear names of SrcTy<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // and all its descendants to lower amount of renaming in LLVM context<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // Renaming occurs because we load all source modules to the same context<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // and declaration with existing name gets renamed (i.e Foo -> Foo.42).<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // As a result we may get several different types in the destination<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> // module, which are in fact the same.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> for (Type *Ty : SpeculativeTypes)<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> if (auto *STy = dyn_cast<StructType>(Ty))<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> if (STy->hasName())<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> STy->setName("");<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">The above doesn’t account for the possibility SrcTy and DstTy can be the same pointer. When they are the same, effectively, the above ends up clearing the name of DstTy.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Is there an assumption that addTypeMapping should never be called with the same types? The code for areTypesIsomorphic does specifically handle the case where DstTy == SrcTy.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Background for the above question…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">I am running into this problem where we have two modules sharing the same types and we are trying to link one module into the other. In our application, we have a common module with inline functions and several
other modules call inline functions from this common module. This code was originally written with LLVM 3.4.2. At that time, the linker API had a PreserveSource mode which allowed for the common module to be preserved so that it can be linked into every other
module. As we are now upgrading our LLVM version, we found that the current API takes ownership of the source module and destroys it after linking. We worked around this problem by cloning the common module before calling Linker::linkInModule. However the
problem is that it still doesn’t work due:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Consider this function in the destination module:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">declare void @foo(%struct.bar * %this1, i8 zeroext %s1) #0<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">and the corresponding function in the source module:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-indent:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">define linkonce_odr void @foo(%struct.bar* %this1, i8 zeroext %s1) #0 {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> :<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">The linking doesn’t succeed (definition of foo doesn’t get copied into the destination module) because of the following code in IRLinker::linkGlobalValueProto:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">Constant *C = NewGV;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">// Only create a bitcast if necessary. In particular, with<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">// DebugTypeODRUniquing we may reach metadata in the destination module<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">// containing a GV from the source module, in which case SGV will be<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">// the same as DGV and NewGV, and TypeMap.get() will assert since it<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">// assumes it is being invoked on a type in the source module.<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">if (DGV && NewGV != SGV) {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> C = ConstantExpr::getPointerBitCastOrAddrSpaceCast(<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> NewGV, TypeMap.get(SGV->getType()));<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">The above results in C to become something like (I suspect that the problem is with the TypeMap which causes a bit-cast to be created). C->dump() shows…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Courier New""> void (%"type 0x5d6c9c0"*, i8)* bitcast (void (%"type 0x5d6bf50"*, i8)* @foo to void (%"type 0x5d6c9c0"*, i8)*)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">This does not cast to a GlobalValue and IRLinker::materialize returns without copying the body of foo:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">GlobalValue *New = dyn_cast<GlobalValue>(*NewProto);<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> if (!New)<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New""> return *NewProto;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt">llvm::verifyModule of the destination module then fails with the following error:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:12.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">Global is external, but doesn't have external or weak linkage!<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:12.0pt;font-family:"Courier New"">void (%0*, i32)* @foo<o:p></o:p></span></p>
</div>
</body>
</html>