access array problem

Hi,
I want to access an array in my instrumentation code. For example:

GlobalVariable:
int *counter; //counter the number of load/store operations in run-time
int *counterArray; //record the load/store addresses

//increase the counter if a load/store is performed
std::vector<Constant *>index(2);
index[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
index[1] = Constant::get(Type::getInt32Ty(Context), 0);
Constant *ElementPtr = ConstantExpr::getGetElementPtr(counter,
&index[0], index.size());
Value *oldcounter = new LoadInst(ElementPtr, "oldcounter", InsertPos);
Value *newcounter = BinaryOperator::Create(Instruction::Add,
oldcounter, ConstantInt::get(Type::getInt64Ty(Context), 1),
"newcounter", InsertPos);
new StoreInst(newcounter, ElmentPtr, InserPos);

//store the memory address to counterArray[oldcounter]
std::vector<Constant*> indexC(2);
indexC[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
indexC[1] = dync_cast(llvm::ConstantInt>(oldcounter);
Constant *ElmentPtr = ConstantExpr::getGetElementPtr(counterArray,
&indexC[0], indexC.size());
......// other codes

Unfortunately, the oldcounter of Value type can not be cast to
ConstantInt, dync_cast returns NULL.
Is there any way to retrieve the integer value from oldcounter?

Thanks!

Hi Tan Guangming,

I want to access an array in my instrumentation code. For example:

GlobalVariable:
int *counter; //counter the number of load/store operations in run-time
int *counterArray; //record the load/store addresses

strictly speaking these are not arrays, they are pointers. Also, you have
written them in some kind of C-style idiom. What are the declarations in
LLVM IR?

//increase the counter if a load/store is performed
std::vector<Constant *>index(2);
index[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
index[1] = Constant::get(Type::getInt32Ty(Context), 0);

The above two lines both compute the same thing (an i32 constant equal to
zero) in two different ways.

Constant *ElementPtr = ConstantExpr::getGetElementPtr(counter,
&index[0], index.size());
Value *oldcounter = new LoadInst(ElementPtr, "oldcounter", InsertPos);
Value *newcounter = BinaryOperator::Create(Instruction::Add,
oldcounter, ConstantInt::get(Type::getInt64Ty(Context), 1),
"newcounter", InsertPos);
new StoreInst(newcounter, ElmentPtr, InserPos);

//store the memory address to counterArray[oldcounter]
std::vector<Constant*> indexC(2);
indexC[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
indexC[1] = dync_cast(llvm::ConstantInt>(oldcounter);

Since oldcounter is not a constant (its value is not known at compile time...)
this is never going to work. Declare the vector to be of Value* not Constant*.
Then you don't need the dynamic cast.

Constant *ElmentPtr = ConstantExpr::getGetElementPtr(counterArray,
&indexC[0], indexC.size());

This line can then not be a ConstantExpr, it has to be an instruction. Again,
it cannot be a constant since the address computed isn't constant (it is not
known at compile time...).

Ciao, Duncan.

于 2011/5/18 14:29, Duncan Sands 写道:

Hi Tan Guangming,

I want to access an array in my instrumentation code. For example:

GlobalVariable:
int *counter; //counter the number of load/store operations in run-time
int *counterArray; //record the load/store addresses

strictly speaking these are not arrays, they are pointers. Also, you have
written them in some kind of C-style idiom. What are the declarations in
LLVM IR?

const Type *IntTy = Type::getInt32Ty(M.getContext());
const Type *ATyC = ArrayType::get(Type::getInt64Ty(M.getContext()), 1);

GlobalVariable *CounterSize = new GlobalVariable(M, ATyC, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATyC), "MemTraceCounterSize");

const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), 3000);
GlobalVariable *Counters = new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "MemTraceCounters");

//increase the counter if a load/store is performed
std::vector<Constant *>index(2);
index[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
index[1] = Constant::get(Type::getInt32Ty(Context), 0);

The above two lines both compute the same thing (an i32 constant equal to
zero) in two different ways.

Constant *ElementPtr = ConstantExpr::getGetElementPtr(counter,
&index[0], index.size());
Value *oldcounter = new LoadInst(ElementPtr, "oldcounter", InsertPos);
Value *newcounter = BinaryOperator::Create(Instruction::Add,
oldcounter, ConstantInt::get(Type::getInt64Ty(Context), 1),
"newcounter", InsertPos);
new StoreInst(newcounter, ElmentPtr, InserPos);

//store the memory address to counterArray[oldcounter]
std::vector<Constant*> indexC(2);
indexC[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
indexC[1] = dync_cast(llvm::ConstantInt>(oldcounter);

Since oldcounter is not a constant (its value is not known at compile time...)
this is never going to work. Declare the vector to be of Value* not Constant*.
Then you don't need the dynamic cast.

So, do you mean that we have no way to use the "oldcounter" as an index to access an array?

In fact, the prolbem is:
I instrument two global variables: "counter", "counterArray", which are allocated in main function.
During runtime, I want to access the "counterArray" using the "counter" as a index, which is also changed at runtime.

于 2011/5/18 14:29, Duncan Sands 写道:

Hi Guangming Tan,

GlobalVariable:
int *counter; //counter the number of load/store operations in run-time
int *counterArray; //record the load/store addresses

strictly speaking these are not arrays, they are pointers. Also, you have
written them in some kind of C-style idiom. What are the declarations in
LLVM IR?

const Type *IntTy = Type::getInt32Ty(M.getContext());
const Type *ATyC = ArrayType::get(Type::getInt64Ty(M.getContext()), 1);

GlobalVariable *CounterSize = new GlobalVariable(M, ATyC, false,
GlobalValue::InternalLinkage,
Constant::getNullValue(ATyC), "MemTraceCounterSize");

so CounterSize is an array of length 1, containing a single 64 bit integer.
Using an array seems rather pointless here.

const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), 3000);
GlobalVariable *Counters = new GlobalVariable(M, ATy, false,
GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "MemTraceCounters");

OK, so Counters is an array of 3000 32 bit integers.

Constant *ElementPtr = ConstantExpr::getGetElementPtr(counter,
&index[0], index.size());

What is "counter", the same things as CounterSize?

//store the memory address to counterArray[oldcounter]
std::vector<Constant*> indexC(2);
indexC[0] = Constant::getNullvalue(Type:getInt32Ty(Context));
indexC[1] = dync_cast(llvm::ConstantInt>(oldcounter);

Since oldcounter is not a constant (its value is not known at compile time...)
this is never going to work. Declare the vector to be of Value* not Constant*.
Then you don't need the dynamic cast.

So, do you mean that we have no way to use the "oldcounter" as an index
to access an array?

No, this is perfectly possible. I think you are confusing constants and
instructions. Instructions are executed at runtime. Constants are known
at compile time. You clearly need an instruction here but you are trying
to create a constant.

Constant *ElmentPtr = ConstantExpr::getGetElementPtr(counterArray,
&indexC[0], indexC.size());

Here you should be using GetElementPtrInst::Create to make a getelementptr
instruction rather than using ConstantExpr::getGetElementPtr which creates a
getelementptr constant (which represents a constant address - the address you
are computing is clearly not constant since it changes every time counter is
incremented).

Ciao, Duncan.

Thank you, Duncan.

I rewrote the code, please help check why it still does not work:

//declare global variable
const Type *IntTy = Type::getInt32Ty(M.getContext());
const Type *ATyC = ArrayType::get(Type::getInt64Ty(M.getContext()), 1);
GlobalVariable *CounterSize = new GlobalVariable(M, ATyC, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATyC), “MemTraceCounterSize”);

const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), 3000);
GlobalVariable *Counters = new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), “MemTraceCounters”);

//get the index
std::vector<Constant*>IndicesC(2);
IndicesC[0] = Constant::getNullValue(Type::getInt32Ty(Context));
IndicesC[1] = ConstantInt::get(Type::getInt32Ty(Context),0);
Constant *ElementPtrC = ConstantExpr::getGetElementPtr(CounterSize,&IndicesC[0],IndicesC.size());
Value *OldCounterSize =new LoadInst(ElementPtrC, “OldCounterSize”, InsertPos);
Value *OldCounterSize =new LoadInst(ElementPtrC, “”, InsertPos);

//create a getelementptr instruction: we want get &Counters[OldCounterSize]
std::vector<Value*>new_idx;
new_idx.push_back(OldCounterSize); // ERROR?
Value *nextaddr = GetElementPtrInst::Create(Counters, new_idx.begin(), new_idx.end(), “”, InsertPos);

Thanks!
于 2011/5/18 16:04, Duncan Sands 写道:

Hi Guangming Tan,

I rewrote the code, please help check why it still does not work:

next time please be more explicit about exactly what goes wrong.

//create a getelementptr instruction: we want get &Counters[OldCounterSize]
std::vector<Value*>new_idx;
new_idx.push_back(OldCounterSize); // ERROR?
Value *nextaddr = GetElementPtrInst::Create(Counters, new_idx.begin(),
new_idx.end(), "", InsertPos);

You need to push an index of zero before pushing the OldCounterSize index.

Ciao, Duncan.

Hi, Duncan,
It does work! Thand you so much!
I'm sorry for my confusing description.
Thanks!

于 2011/5/18 17:20, Duncan Sands 写道: