値をロードするときにいくつか問題があります。問題を示すためにコンパイラが生成する IR の簡単な例を次に示します。
define i32 @main() {
entry:
%a = alloca i32 ; <i32*> [#uses=2]
store i32 1, i32* %a
%r = load i32* %a ; <i32> [#uses=1]
br label %Return
Return: ; preds = %entry
ret i32 %r
}
しかし、1 を返す代わりに 16777216 を返します。さまざまな値でプログラムをテストしましたが、整数値の内部バイナリ表現の問題のようです。
編集済み: 上記のコードを生成するためにコンパイラが行う llvm の呼び出しのトレースを示します。bloques.back().last は Value* 型で、bloques.back().bl は BasicBlock* (現在のブロック) です。
bloques.back().last = dyn_cast<Value>(ConstantInt::get(
Type::getInt32Ty(getGlobalContext()), $1, true)); // $1 is an int
AllocaInst *alloc = new AllocaInst(
Type::getInt32Ty(getGlobalContext()), izq.c_str(), bloques.back().bl);
Value *derecha = bloques.back().last;
StoreInst *s = new StoreInst(derecha, alloc, false, bloques.back().bl);
bloques.back().last = alloc;
LoadInst* v1 = new LoadInst(bloques.back().last, "r", false, bloques.back().bl);
bloques.back().last = v1;
BasicBlock* blockReturn = BasicBlock::Create(getGlobalContext(), "Return", Main);
Value* last = bloques.back().last;
BranchInst::Create(blockReturn, bloques.back().bl);
ReturnInst::Create(getGlobalContext(), last, blockReturn);
IR 表現に対応するソース コードは次のようになります。
a = 1
return a
Edit2:コードを生成した後、JIT を介して実行を開始する前に、メイン関数でこれを行います。
ExecutionEngine *EE = EngineBuilder(M).create();
string str = EE->getTargetData()->getStringRepresentation();
str[0] = 'e';
M->setDataLayout(str);
if (verifyModule(*M)) {
errs() << argv[0] << ": Error building the function!\n";
return 1;
}
vector<GenericValue> noargs;
GenericValue GV = EE->runFunction(Main, noargs);
outs() << "Result: " << GV.IntVal << "\n";
return 0;
解決済み: ついに解決策を見つけました。エンディアンを変更するには、次のようにします (少しスパゲッティですが、機能します)。
Module *M = new Module("pythoncode", getGlobalContext());
ExecutionEngine *EE2 = EngineBuilder(M).create();
string str = EE2->getTargetData()->getStringRepresentation();
str[0] = 'e';
cout << str << endl;
M->setDataLayout(str);
ExecutionEngine *EE = EngineBuilder(M).create();
前もって感謝します。
サントス・メリノ。