2012-11-12 70 views
0

我正在嘗試編寫一些編譯器並使用LLVM生成中間代碼。不幸的是,LLVM文檔不是很好,甚至有些混亂。*值沒有被生成到LLVM代碼

目前我已經完成了詞法,語法和AST。我也在跟隨在互聯網上找到的一些例子。我當前的AST的工作原理如下:它具有抽象基類Tree *,從其中繼承其他樹(因此,像一個用於變量定義,一個用於語句列表,一個用於二進制表達式等)。

我想實現的變量定義,因此對於輸入

class Test{ 
    int main() 
    { 
    int x; 
    } 
} 

我想LLVM輸出爲:

; ModuleID = "Test" 

define i32 @main() { 
entry: 
    %x = alloca i32 
    return i32 0 
} 

然而,現在我可以得到%×= ALLOCA 123-132部分到創建main函數的部分,但實際輸出缺少%x = alloca i32。所以,我得到的輸出如下:

; ModuleID = "Test" 

define i32 @main() { 
entry: 
    return i32 0 
} 

我的代碼生成()變量聲明爲以下所示的(現在符號表只是一個名單,我想在讓事情儘可能的簡單此刻):

llvm::Value *decafStmtList::Codegen() { 

string name = SyandTy.back(); // Just a name of a variable 
string type = SyandTy.front(); // and its type in string format 
Type* typeVal = getLLVMType(decafType(str2DecafType(type))); // get LLVM::*Type representation 
llvm::AllocaInst *Alloca = Builder.CreateAlloca(typeVal, 0, name.c_str()); 
Value *V = Alloca; 
return Alloca;//Builder.CreateLoad(V, name.c_str()); 
} 

在那裏我生成我@main的部分如下: 注:我已經註釋掉print_int功能(這是我將在以後用於打印的東西的功能,但現在我不需要它)。如果我將取消print_int函數的註釋,TheFunction將不會通過驗證器(TheFunction) - >抱怨模塊被破壞,並且參數與簽名不匹配。

Function *gen_main_def(llvm::Value *RetVal, Function *print_int) { 
    if (RetVal == 0) { 
    throw runtime_error("something went horribly wrong\n"); 
    } 
    // create the top-level definition for main 
    FunctionType *FT = FunctionType::get(IntegerType::get(getGlobalContext(), 32), false); 
    Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "main", TheModule); 
    if (TheFunction == 0) { 
    throw runtime_error("empty function block"); 
    } 
    // Create a new basic block which contains a sequence of LLVM instructions 
    BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); 
    // All subsequent calls to IRBuilder will place instructions in this location 
    Builder.SetInsertPoint(BB); 

    /* 
    Function *CalleeF = TheModule->getFunction(print_int->getName()); 
    if (CalleeF == 0) { 
    throw runtime_error("could not find the function print_int\n"); 
    }*/ 
    // print the value of the expression and we are done 
// Value *CallF = Builder.CreateCall(CalleeF, RetVal, "calltmp"); 



// Finish off the function. 
// return 0 from main, which is EXIT_SUCCESS 
    Builder.CreateRet(ConstantInt::get(getGlobalContext(), APInt(32, 0))); 
    return TheFunction; 
} 

如果有人知道爲什麼我的Alloca對象沒有被生成,請幫助我 - 任何提示將不勝感激。

謝謝

編輯:

代碼生成從語法叫:

start: program 

program: extern_list decafclass 
{ 


    ProgramAST *prog = new ProgramAST((decafStmtList *)$1, (ClassAST *)$2); 
    if (printAST) { 
     cout << getString(prog) << endl; 
    } 
    Value *RetVal = prog->Codegen(); 
    delete $1; // get rid of abstract syntax tree 
    delete $2; // get rid of abstract syntax tree 

    // we create an implicit print_int function call to print 
    // out the value of the expression. 

    Function *print_int = gen_print_int_def(); 
    Function *TheFunction = gen_main_def(RetVal, print_int); 
    verifyFunction(*TheFunction); 
} 

編輯:我想通了,基本上createAlloca必須是basicblock後產生主時調用;

回答

0

這裏有兩個奇怪的事情:

  1. 所有你要做的就是調用Builder.CreateRet ......我看不出,除非你調用的東西,創建相應的有可能是在主任何代碼說明。特別是,你似乎永遠不會調用CodeGen部分。

  2. 您將大小零傳遞給CreateAlloc。我認爲大小應該是單個變量的大小。

此外,請確保在生成代碼後不要調用任何LLVM優化傳遞。那些通行證將優化價值(它從未使用,因此死代碼)。

+0

感謝您的快速回復,以下是一些進一步的說明:1。這正是我的想法 - LLVM中應該有一些函數可以創建alloca的指令,但我真的找不到任何函數。所以,我假設CreateAlloca這樣做。你知道在main中創建指令的函數嗎? Codegen是從語法中調用的。 2.我仍然不明白CreateAlloca的第二個參數的含義,文檔指定了CreateAlloca(Type * Ty,Value * ArraySize = 0,const Twine&Name =「」)[inline] – user1039063

+0

此外,在函數* gen_main_def(){...}我可以放置RetVal-> dump(),它會打印%x = alloca i32,因此它會產生正確的輸出。它只是失蹤了一些未知的我以後的理由。我也相信是應該有一個主要塊內的函數來存儲%x = alloca i32,但我在llvm.org上找不到任何相關的函數 – user1039063