1

LLVM 3.3 C++-API を使用しています。私のコードは、 を使用して配列を作成しConstantArray::get、再帰コードを使用して多次元配列を作成します (上記のように、最も内側のランクは最初に Constant*s のベクトルに変換され、次にそれを使用して次の最も内側のランクが初期化されます)。

ConstantDataArray::isElementTypeCompatible配列の要素の型が述語を満たす場合は、を使用して初期化する必要があると言って、これを最適化しようとしましたConstantDataArray::get

私が何を意味するかを示すためのより具体的な例を次に示します。

  1. 作成したい配列が C++ で次のように宣言されるとします。

    int x[2][3] = {{1,2,3},{4,5,6}};

  2. 最も内側のランク (int[3] 型) は単純な配列型であるため、2 つの CDA が作成されます。

  3. 次のランクは、2 つの int[3] の配列です。単純なタイプではないのでレギュラーConstantArrayを作成。引数はArrayRef<Constant*>、2 つの CDA を含む です。

ステップ 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]は、3 つの配列の 2 つの配列です。operator[]として配列型を構築するためにオーバーロードしていますi64[2][3]。ここで、は、およびオーバーロードi64を保持するオブジェクトです。問題は、これが 2 つの配列の 3 つの配列の配列を構築することです。IntegerType*operator[]

4

0 に答える 0