Initialising global Array

Hi,

I try to create a array that has a nonzero initialiser:

What i do is, first create the array type.

> const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

Then create some constant values for the initializer.

> std::vector<Constant*> Initializer; Initializer.reserve(NumEdges);
> APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);
> APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

Create the global array, there is no initializer yet.

> GlobalVariable *Counters =
> new GlobalVariable(ATy, false, GlobalValue::InternalLinkage,
> Constant::getNullValue(ATy), "OptimalEdgeProfCounters", &M);

Then exactly "NumEdges" constants are pushed to the "Initializer":

> Initializer[i] = zeroc;
> ..
> Initializer[i] = minusonec;
> ..

And then I set the initializer for the array:

> Constant *init = llvm::ConstantArray::get(ATy, Initializer);
> Counters->setInitializer(init);

What am I doing wrong? I still get:

> @OptimalEdgeProfCounters = internal global [2 x i32] zeroinitializer; <[2 x i32]*> [#uses=2]

Thanks, Andi

Andreas Neustifter wrote:

Hi,

I try to create a array that has a nonzero initialiser:

What i do is, first create the array type.

> const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

Then create some constant values for the initializer.

> std::vector<Constant*> Initializer; Initializer.reserve(NumEdges);

I ran the following two functions in a ModulePass. The Initializer initialization is the difference.

static void andiTest1(Module &M) {
  int NumEdges = 4;
  const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

  std::vector<Constant*> Initializer; Initializer.reserve(NumEdges);
  APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);
  APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

  GlobalVariable *Counters = new GlobalVariable(ATy, false,
      GlobalValue::InternalLinkage, Constant::getNullValue(ATy),
      "OptimalEdgeProfCounters1", &M);

  Initializer[0] = zeroc;
  Initializer[1] = minusonec;
  Initializer[2] = minusonec;
  Initializer[3] = zeroc;

  Constant *init = llvm::ConstantArray::get(ATy, Initializer);
  Counters->setInitializer(init);
  DOUT << "Initializer:: \n";
  for( int i = 0; i < Initializer.size(); ++i ) {
    DOUT << "Initializer["<<i<<"]: " << Initializer[i] << "\n";
  }
}

static void andiTest2(Module &M) {
  int NumEdges = 4;
  const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

  std::vector<Constant*> Initializer = std::vector<Constant*>(NumEdges);
  APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);
  APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

  GlobalVariable *Counters = new GlobalVariable(ATy, false,
      GlobalValue::InternalLinkage, Constant::getNullValue(ATy),
      "OptimalEdgeProfCounters2", &M);

  Initializer[0] = zeroc;
  Initializer[1] = minusonec;
  Initializer[2] = minusonec;
  Initializer[3] = zeroc;

  Constant *init = llvm::ConstantArray::get(ATy, Initializer);
  Counters->setInitializer(init);
  DOUT << "Initializer:: \n";
  for( int i = 0; i < Initializer.size(); ++i ) {
    DOUT << "Initializer["<<i<<"]: " << Initializer[i] << "\n";
  }
}

Hi!

Slobodan Pejic wrote:

I ran the following two functions in a ModulePass. The Initializer
initialization is the difference.

static void andiTest1(Module &M) {
  int NumEdges = 4;
  const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

  std::vector<Constant*> Initializer; Initializer.reserve(NumEdges);
  APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);
  APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

  GlobalVariable *Counters = new GlobalVariable(ATy, false,
      GlobalValue::InternalLinkage, Constant::getNullValue(ATy),
      "OptimalEdgeProfCounters1", &M);

  Initializer[0] = zeroc;
  Initializer[1] = minusonec;
  Initializer[2] = minusonec;
  Initializer[3] = zeroc;

  Constant *init = llvm::ConstantArray::get(ATy, Initializer);
  Counters->setInitializer(init);
  DOUT << "Initializer:: \n";
  for( int i = 0; i < Initializer.size(); ++i ) {
    DOUT << "Initializer["<<i<<"]: " << Initializer[i] << "\n";
  }
}

static void andiTest2(Module &M) {
  int NumEdges = 4;
  const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

  std::vector<Constant*> Initializer = std::vector<Constant*>(NumEdges);
  APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);
  APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

  GlobalVariable *Counters = new GlobalVariable(ATy, false,
      GlobalValue::InternalLinkage, Constant::getNullValue(ATy),
      "OptimalEdgeProfCounters2", &M);

  Initializer[0] = zeroc;
  Initializer[1] = minusonec;
  Initializer[2] = minusonec;
  Initializer[3] = zeroc;

  Constant *init = llvm::ConstantArray::get(ATy, Initializer);
  Counters->setInitializer(init);
  DOUT << "Initializer:: \n";
  for( int i = 0; i < Initializer.size(); ++i ) {
    DOUT << "Initializer["<<i<<"]: " << Initializer[i] << "\n";
  }
}

Yes, the first variant (mine) does not work, the second does. (Don't get
it why, tough...)

But when I use the initialisation of "Initializer" you suggested in my
"production code" it still does not work :frowning:

But thanks for your effort, I really appreciate it!

Andi

Hi,

I try to create a array that has a nonzero initialiser:

What i do is, first create the array type.

const ArrayType *ATy = ArrayType::get(Type::Int32Ty, NumEdges);

Then create some constant values for the initializer.

std::vector<Constant*> Initializer; Initializer.reserve(NumEdges);

It looks like you may be using reserve when resize is needed.

APInt zero(32,0); Constant* zeroc = ConstantInt::get(zero);

APInt minusone(32,-1); Constant* minusonec = ConstantInt::get(minusone);

Create the global array, there is no initializer yet.

GlobalVariable *Counters =

new GlobalVariable(ATy, false, GlobalValue::InternalLinkage,

                    Constant::getNullValue(ATy), "OptimalEdgeProfCounters", &M);

Then exactly "NumEdges" constants are pushed to the "Initializer":

Initializer[i] = zeroc;

If Initializer hasn't been resized, this access will be
out of bounds.

Dan