简体   繁体   中英

LLVM IR Array Move with c++ api

I have the following problem with llvm and c++: Given an array, I want to shift every entry of that array by one to the right, ie, I want to implement the following c code:

int arr[5];
for(int i=1;i<5;++i){
   arr[i] = arr[i-1];
}

I tried the following c++ code:

  IntegerType *Int32Ty = IntegerType::getInt32Ty(M.getContext(););
  GlobalVariable *arrVariable;
  arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
                 GlobalValue::ExternalLinkage, 0, "__arr");
  for(int i=0;i<ARRAY_LENGTH;++i){
     Constant* fromIdx =  Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i-1));
     Value *fromLocPtrIdx =   IRB.CreateGEP(arrVariable, fromIdx);
     Constant* toIdx =  Constant::getIntegerValue(Int32Ty, llvm::APInt(32, i));
     Value *toLocPtrIdx =   IRB.CreateGEP(arrVariable, toIdx);
     StoreInst *MoveStoreInst = IRB.CreateStore(fromLocPtrIdx,toLocPtrIdx);
  }

where __arr is defined as:

__thread u32  __arr[ARRAY_LENGTH];

However, when compiling, this yields the following error message:

/usr/bin/ld: __arr: TLS definition in ../inject.o section .tbss mismatches non-TLS reference in /tmp/test-inject.o

What is the right way to move values in an arrays using the llvm c++ api?

You need to specify that your global variable is thread_local .

The way to do that is to add the thread-local mode to your global creation:

arrVariable = new GlobalVariable(M, PointerType::get(Int32Ty, 0), false,
                 GlobalValue::ExternalLinkage, 0, "__arr", nullptr, InitialExecTLSModel);

The exact mode depends on what your target is, but I think InitialExecTLSModel is a generally "good starting point".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM