[LLVMdev] RE: Question about Global Variable

Qiuyu Zhang qiuyu at ucla.edu
Tue Feb 1 21:52:39 PST 2005


Thanks for your reply.

After I change Cstr to gI, it compiled successfully. Thanks again. 

Another question is for constructing getelementpt.

// C code
char gStrA[10] = "test str"; // here is Global variable,gStrA and initializer "test str"
char gStrB[10]= "test str2";
main(){
    int = i;
    char *pGVars[20]; // here, the pGVar is for storing the address of each initializer, i.e. "test str"
    pGVars[0] = gStrA;
    pGVars[1] = gStrB;

    // change the content of gStrA
    for(i=0;i<5;i++){
        pGVars[0][i] ^= 0x27; 
   }
}

the following IR code is the loop part code which is corresponding to the above C code
no_exit:                ; preds = %loopentry
        %tmp.31 = getelementptr [3 x sbyte*]* %pGVars, int 0, int 0               ; <sbyte**> [#uses=1]
        %tmp.32 = load sbyte** %tmp.31          ; <sbyte*> [#uses=1]
        %tmp.33 = load int* %i          ; <int> [#uses=1]
        %tmp.34 = getelementptr sbyte* %tmp.32, int %tmp.33             ; <sbyte*> [#uses=1]

I am trying to construct all those IR instructions, for the first three, it is ok, as the following
       
 GetElementPtrInst *GEP = new GetElementPtrInst( pGVars, idxVec, "GetAryElement", InsertPos);
 Value *ldAddr = new LoadInst(GEP,"LdAryAddr",InsertPos);
 Value *ldAddr1 = new LoadInst(numidx, "idx_i", InsertPos);

After this I need construct another getelementptr, and from the above IR code, the second getelementptr take the result of load as parameters. But there is no such prototype construction api for this case.  The correct one should be as the following, 

GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
      const std::string &Name = "", Instruction *InsertBefore =0);
  GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,    // or Idx1, Idx2
      const std::string &Name, BasicBlock *InsertAtEnd);

How could I create the fourth IR ? Thanks 

        %tmp.35 = getelementptr [3 x sbyte*]* %pGVars, int 0, int 0               ; <sbyte**> [#uses=1]
        %tmp.36 = load sbyte** %tmp.35          ; <sbyte*> [#uses=1]
        %tmp.37 = load int* %i          ; <int> [#uses=1]
        %tmp.38 = getelementptr sbyte* %tmp.36, int %tmp.37             ; <sbyte*> [#uses=1]
        %tmp.39 = load sbyte* %tmp.38           ; <sbyte> [#uses=1]
        %tmp.40 = xor sbyte %tmp.39, 39         ; <sbyte> [#uses=1]
        store sbyte %tmp.40, sbyte* %tmp.34
        %tmp.41 = load int* %i          ; <int> [#uses=1]
        %inc = add int %tmp.41, 1               ; <int> [#uses=1]
        store int %inc, int* %i
        br label %loopentry

Qiuyu

> On Sun, 30 Jan 2005, Qiuyu Zhang wrote:
> > Hi,
> >
> > Sorry for bothering you guys again.
> >
> > I got problem when I am trying to recover the Global Variable Initial value. What I did is like the following
> >
> > ConstantArray *Cstr = dyn_cast<ConstantArray>(gI->getInitializer());
> 
> > // the above instruction enable me to get the content of initial string 
> > of global variable, like char a[10] ="test global";
> 
> Yup.
> 
> > And then I make some change for the Cstr and write it back to the global 
> > variable by gI->setInitializer(Constant *); Meanwhile I am trying to put 
> > a routine (constructing IR routine) into entry of main function, which 
> > is for recover initial vaule of global variable to the original string. 
> > In this routine,
> 
> Ok.
> 
> > Type *PointerAryType  =  ArrayType::get(PointerType::get(Type::SByteTy) , 20);
> > AllocaInst *PointerAry = new AllocaInst(PointerAryType , 0 , "AddrOfGstr", BB);
> 
> Okay, this should be fine.
> 
> > // Here, I tried to insert IR like alloca [20 x sbyte *], for C code, it 
> > is char *AddrOfGstr[20]; which pointer array is for storing the pointer 
> > of initial value of each // global variable.
> >
> > So next step in my Pass, I should get the pointer of initial value of 
> > each global variable and assign them the AddrOfGstr[i]. Here, I got 
> > problem, I can get initial value by gI->getInitializer(), but this 
> > pointer is not the memory address of the initial value, it is a pointer 
> > of constant, like constant *. I cannot assign it to the AddrOfGstr[i]. 
> > How could I get memory address the initial vaule, not the pointer of 
> > constant?
> 
> Okay, you do not want to use the initializer here.  Instead, you want the 
> *address* of the global.  The address of the global is represented by the 
> global variable object itself.  In your code above, the 'gI' variable 
> should be a pointer to a GlobalVariable.  This Value* will have a 
> pointer-to-array-of-byte type.
> 
> > I tried to use the following way,
> >
> > std::vector <Value *> idxVec;
> > Value *Zero1 = ConstantInt::get(Type::IntTy , 0);
> > Value *Zero2 = ConstantInt::get(Type::IntTy , 0);
> >
> > idxVec.push_back(Zero1);
> > idxVec.push_back(Zero2);
> >
> > Constant *pStr = ConstantExpr::getGetElementPtr(Cstr, idxVec); // trying to get pointer of initial value
> 
> Very close.  Try using gI instead of Cstr.
> 
> > Is the question clear? How could I fix it? Thanks so much.
> 
> Try the above, and please let me know if it doesn't help!
> 
> -Chris
> 






More information about the llvm-dev mailing list