我正在寫一個LLVM通道,將原始程序中浮點變量的類型改爲long double。一個玩具測試程序是:如何通過編寫LLVM通道將原始程序中浮點變量的類型改爲long double?
int main(){
double i = 0.0000000000000001;
if(i + 1 > 1)
printf("correct answer");
else
printf("wrong answer");
return 0;
}
我的通行證需要改變我的類型爲「長雙」。 原始程序的IR與轉換程序之間有五個不同的地方。
< %i = alloca x86_fp80, align 16
---
> %i = alloca double, align 8
< store x86_fp80 0xK3FC9E69594BEC44DE000, x86_fp80* %i, align 16
< %0 = load x86_fp80, x86_fp80* %i, align 16
< %add = fadd x86_fp80 %0, 0xK3FFF8000000000000000
< %cmp = fcmp ogt x86_fp80 %add, 0xK3FFF8000000000000000
---
> store double 1.000000e-16, double* %i, align 8
> %0 = load double, double* %i, align 8
> %add = fadd double %0, 1.000000e+00
> %cmp = fcmp ogt double %add, 1.000000e+00
我的通行證做上述轉換的要點如下:
virtual bool runOnFunction(Function &F) {
std::string svariable ("i");
const ValueSymbolTable& symbolTable = F.getValueSymbolTable();
Value* target = symbolTable.lookup(svariable);
AllocaInst* old_target = dyn_cast<AllocaInst>(target);
errs() <<"old_target: " << *target << "\n";
errs() <<"num of old_target_uses:" << old_target->getNumUses() <<"\n";
//get the type of long double and construct new AllocaInst
LLVMContext &context = F.getContext();
Type* type = Type::getX86_FP80Ty(context);
unsigned alignment = 16;
AllocaInst* new_target = new AllocaInst(type, 0, alignment, "new", old_target);
new_target->takeName(old_target);
// iterating through instructions using old AllocaInst
Value::use_iterator it = old_target->use_begin();
for(; it != old_target->use_end(); it++) {
Value * temp = it->get();
errs() <<"temp:" << *temp <<"\n";
//transform() is under construction
transform(it, new_target, type, alignment);
}
old_target->eraseFromParent();
return false;
}
應該有我如在原計劃的IR翻番相關四條指令:
> store double 1.000000e-16, double* %i, align 8
> %0 = load double, double* %i, align 8
> %add = fadd double %0, 1.000000e+00
> %cmp = fcmp ogt double %add, 1.000000e+00
但並不如上述預期通的輸出:
old_target: %i = alloca double, align 8
num of old_target_uses:2
temp: %0 = alloca double, align 8
temp: %0 = alloca double, align 8
所以我的第一個問題是爲什麼getNumUses()和use_iterator沒有返回正確答案,我在通行證的輪廓中是否以錯誤的方式使用它們?我的第二個問題是在我的transform()函數中,我需要枚舉LoadInst,StoreInst,BinaryOperation等各種指令,並用新類型重新構造它們,對不對?
預先:)
你爲什麼選擇在LLVM級別而不是在(例如使用鏘)源代碼級攻擊這個問題? – eush77
非常感謝您的意見。在LLVM IR級別攻擊它,我將能夠方便地支持任何編譯(或將編譯)到LLVM的源語言,包括C/C++,Fortran,R等。 – Sue