<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle" type="text/css">P {margin-top:0;margin-bottom:0;}</style>
</head>
<body ocsi="0" fpstyle="1">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">Hi<br>
<br>
During a pass, the XCore target lowers thread local global variables by turning them into global variable arrays indexed by the (max 8) thread ID.<br>
(see XCoreLowerThreadLocal.cpp)<br>
<br>
This works fine for instructions e.g. <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">GetElementPtrInst<br>
But can't be done for constants e.g. G</span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">etElementPtrConstantExpr<br>
<br>
Thus I would like to replace G</span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">etElementPtrConstantExpr
 with </span></font></span></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">GetElementPtrInst
 when it is accessing a thread local global variable.<br>
(Other constant expression ignored for now).<br>
<br>
My attempt (example code below) has revealed my lack of understanding of llvm.<br>
For one thing I need to distinguish when the </span></font></span></span></font></span></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">G</span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">etElementPtrConstantExpr</span></font></span>
 is a child of an instruction and hence can be changed into an instruction itself.<br>
<br>
When offered:<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">@tl
 = external thread_local global [1 x i32]<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">define
 i32* @tli () {<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">   
 ret i32* getelementptr([1 x i32]* @tl, i32 0, i32 0)<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">}<br>
the example code prints:</span></font></span></span></font></span></span></font></span><br>
    <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">@tl
 = external thread_local global [1 x i32]<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">ConstantExpr
 ops...<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">@tl
 = external thread_local global [1 x i32]<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">i32
 0<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">i32
 0<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">Replace...<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">i32*
 getelementptr inbounds ([1 x i32]* @tl, i32 0, i32 0)<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">with...<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"> 
 <badref> = getelementptr inbounds [1 x i32]* @tl, i32 0, i32 0<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">leave
 for backend error<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">Instruction
 does not dominate all uses!<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"> 
 <badref> = getelementptr inbounds [1 x i32]* @tl, i32 0, i32 0<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"> 
 ret i32* <badref><br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">Broken
 module found, compilation aborted!<br>
<br>
<br>
Q: Is my approach generally correct?<br>
I am also concerned that:<br>
</span></font></span></span></font></span></span></font></span>    <span style="background-color:white;">
<font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">@i
 = constant i32* getelementptr ([1 x i32]* @tl, i32 0, i32 0)<br>
must be skipped and not replaced.<br>
Hence '</span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">replaceAllUsesWith'
 is a bad idea!<br>
<br>
</span></font></span></span></font></span></span></font></span>I plan to explore the parent node next to verify its type and replace its
</span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span>G<span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">etElementPtrConstantExpr</span></font></span>
 operand if it is an instruction.<br>
Q: Is this the right direction?<br>
<br>
</span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span>Thank you.<br>
<br>
Robert<br>
<br>
<br>
namespace {  struct ValuePair { Value * CE; Value * Inst; };  }<br>
<br>
static bool hasNonInstructionUse(GlobalVariable *GV) {<br>
</span></font></span></span></font></span></span></font></span>  // first try to replace
<span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span>G<span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">etElementPtrConstantExpr
 with </span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span></span></font></span>GetElementPtrInst
<br>
<span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"> 
 SmallVector<ValuePair,4> Replace;<br>
  for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI != E; ++UI) {<br>
    ConstantExpr * CE = dyn_cast<ConstantExpr>(*UI);<br>
    if ( CE && CE->getOpcode() == Instruction::GetElementPtr) {<br>
      dbgs() << "ConstantExpr ops...\n";<br>
      SmallVector<Value*,4> OpVec;<br>
      for (ConstantExpr::op_iterator OpIt = CE->op_begin(), E = CE->op_end(); OpIt != E; ++OpIt) {<br>
        OpVec.push_back(cast<Value>(OpIt));<br>
        cast<Value>(OpIt)->dump();<br>
      }<br>
      ArrayRef<Value*> Ops(OpVec);<br>
      Instruction * NewInst = GetElementPtrInst::CreateInBounds(Ops[0], Ops.slice(1), CE->getName() );<br>
      ValuePair vp = {CE,NewInst};<br>
      Replace.push_back(vp);<br>
    }<br>
  }<br>
  for (SmallVectorImpl<ValuePair>::const_iterator I = Replace.begin(),<br>
                                               E = Replace.end();<br>
            I != E; ++I) {<br>
    dbgs() << "Replace...\n"; I->CE->dump();<br>
    dbgs() << "with...\n"; I->Inst->dump();<br>
    I->CE->replaceAllUsesWith(I->Inst);<br>
  }<br>
<br>
  // we can't lower non instruction - leave to error later<br>
  for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI != E; ++UI)<br>
    if (!isa<Instruction>(*UI)) {<br>
</span></font></span></span></font></span></span></font></span><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"> 
     dbgs() << "leave for backend error\n";<br>
</span></font></span></span></font></span></span></font></span>      return true;</span></font></span></span></font></span></span></font></span><br>
  <span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr"><span style="background-color:white;"><font color="black" face="Tahoma" size="2"><span style="font-size:10pt;" dir="ltr">}<br>
  return false;<br>
}<br>
</span></font></span></span></font></span></span></font></span><br>
</div>
</body>
</html>