我正在使用LLVM 3.3 C ++ - API。我的代码使用ConstantArray::get
创建数组,使用递归代码创建多维数组(最里面的等级首先转换为Constant * s的向量,如上所述,然后用于初始化下一个最内层的等级,依此类推)。
我试图通过说如果数组的元素类型满足ConstantDataArray::isElementTypeCompatible
谓词来优化它,那么应该使用ConstantDataArray::get
初始化它。
这里有一个更具体的例子来说明我的意思:
假设我要创建的数组将在C ++中声明为:
int x [2] [3] = {{1,2,3},{4,5,6}};
最里面的等级(类型int [3])是一个简单的数组类型,因此创建了两个CDA。
下一个排名是两个int [3]的数组。它不是一个简单的类型,因此创建了常规ConstantArray
。参数是包含两个CDA的ArrayRef<Constant*>
。
在步骤3,ConstantArray
会抱怨,因为初始化程序没有完全正确的类型。这是消息:
.../llvm-3.3.src/lib/IR/Constants.cpp:754:
static llvm::Constant* llvm::ConstantArray::get(llvm::ArrayType*,
llvm::ArrayRef<llvm::Constant*>):
Assertion `V[i]->getType() == Ty->getElementType()
&& "Wrong type in array element initializer"' failed.
当元素类型足够简单时,我ConstantDataArray
代替了ConstantArray
,但也许我错了。了解它的正确方法是什么?
这看起来像我的代码中的错误(在LLVM之外)。 ConstantDataArray
似乎确实是ConstantArray
的透明替代品。
这是我用来展示问题的代码。它实际上没有任何来自LLVM的投诉:
// int[2][3] = {{1,2,3},{4,5,6}};
IntegerType* i64 = IntegerType::get(mod->getContext(), 64);
Constant* one = ConstantInt::get(i64, 1);
Constant* two = ConstantInt::get(i64, 2);
Constant* three = ConstantInt::get(i64, 3);
Constant* four = ConstantInt::get(i64, 4);
Constant* five = ConstantInt::get(i64, 5);
Constant* six = ConstantInt::get(i64, 6);
ArrayType* int_3 = ArrayType::get(i64, 3);
ArrayType* int_2_3 = ArrayType::get(int_3, 2);
// Constant* array123 = ConstantArray::get(int_3, std::vector<Constant*>{one,two,three});
Constant* array123 = ConstantDataArray::get(mod->getContext(), std::vector<uint64_t>{1,2,3});
// Constant* array456 = ConstantArray::get(int_3, std::vector<Constant*>{four,five,six});
Constant* array456 = ConstantDataArray::get(mod->getContext(), std::vector<uint64_t>{4,5,6});
Constant* array = ConstantArray::get(int_2_3, std::vector<Constant*>{array123, array456});
如果有人感兴趣,断言源于我颠倒数组范围。 int[2][3]
是两个三个数组的数组。我正在重载operator[]
以将数组类型构建为i64[2][3]
,其中i64
是一个包含IntegerType*
并重载operator[]
的对象。问题是这会构建一个由三个两个数组组成的数组。