I have modified Kaleidoscope's if-then-else codegen, to support if-then (no else clause), for a non-functional language. I'm unable to get the merge block (after the 'then') to be created in the IR.
I have removed the Phi node creation, because (0) the phi node needs to merge 2 branches of execution and I only really have one branch (1) it's not really required in a non-functional language context? (2) the phi requires two legs of the same type and the statement above the 'if' statement might return a different type.
The if-then codegen is:
static IRBuilder<> Builder(TheContext);
:
Value* IfThenExprAST::Codegen() {
Value* CondV = Cond->Codegen();
CondV = Builder.CreateICmpNE(CondV, Builder.getInt1(0), "ifcond");
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock* ThenBB = BasicBlock::Create(TheContext, "then", TheFunction);
BasicBlock* MergeBB = BasicBlock::Create(TheContext, "ifcont");
Builder.CreateCondBr(CondV, ThenBB, MergeBB);
Builder.SetInsertPoint(ThenBB);
llvm::Value* ThenV;
for(std::vector<ExprAST*>::iterator it = Then.begin(); it != Then.end(); ++it)
ThenV = (*it)->Codegen();
Builder.CreateBr(MergeBB);
return CondV;
}
The resulting IR is:
:
br i1 true, label %then, label %ifcont
then: ; preds = %entry
br label %ifcont
:
ret double 1.000000e+01
Notice that there is no 'ifcont' label generated in the IR.
How do I tell the builder to insert the ifcont label after the 'then' clause?
I solved this by adding the following 2 lines just before 'return CondV;'
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
Related
Recently I added function verification to every function generation and found this error:
Terminator found in the middle of a basic block!
label %then
Currently for a return statement I just generate a ret and not anything else, but things go wrong when it's inside a conditional block with br after it. Seems like you can't put terminators in the middle of a block, but I can't decide how I should solve it. Using phi node seems weird as the code doesn't necessarily return a value on each branch, and I cannot figure out a way to pass return value to the phi node. Also, I'm unsure if using some kind of signals to indicate codegen to stop will make things more complicated. That's why I want to know if there's a way to automatically eliminate code after the first terminator.
Here's a fibbonacci function for example, generated from code:
define weak i64 #.testModule.recFib(i64 %n) {
entry:
%_bool.0 = icmp eq i64 %n, 1
%_bool.1 = icmp eq i64 %n, 2
%_bool.2 = or i1 %_bool.0, %_bool.1
br i1 %_bool.2, label %then, label %continue
then: ; preds = %entry
ret i64 1
br label %continue
continue: ; preds = %then, %entry
%_int.0 = sub i64 %n, 1
%_int.1 = call i64 #.testModule.recFib(i64 %_int.0)
%_int.2 = sub i64 %n, 2
%_int.3 = call i64 #.testModule.recFib(i64 %_int.2)
%_int.4 = add i64 %_int.1, %_int.3
ret i64 %_int.4
}
I am trying to copy a set of instructions from source Basic block to 2 or more destination basic blocks. After copying I wish to remove the instructions from the source basic block, then delete source basic block.
After struggling a bit with the API I get the following results.
Destination basic blocks
then: ; preds = %entry
store i8000000 0, i8000000* %res
;after copying
**Issue-----> %res45 = load i8000000, i8000000* %res
ret i8000000 %res4 <----- Issue**
br label %continuation
else: ; preds = %entry
store i8000000 0, i8000000* %res
;after copying
**Issue----->%res46- = load i8000000, i8000000* %res
ret i8000000 %res4 <----- Issue**
br label %continuation
Source basic block
continuation: ; preds = %else, %then
%iftmp = phi i32 [ 5, %then ], [ 9, %else ]
store i32 %iftmp, i32* %datasize
; 3 lines below to be copied and then this whole basic block needs to be deleted.
store i8000000 0, i8000000* %res
%res4 = load i8000000, i8000000* %res
ret i8000000 %res4
}
relevant chunk of Code
// startInst/endInst are iterators to the instructions where I start/finish copying.
for (auto i = startInst, e = endInst; i != e; ++i) {
Instruction* temp = i->clone();
temp->insertBefore(terminatorInst);
Value* copyInstVal = temp;
Value* originalInstVal = &(*i);
copyInstVal->setName(originalInstVal->getName());
}
My issue
I have been using Instruction::clone() to copy the instructions and then set a name for this clone.
My major issue is that I need to maintain the same dependency between the instructions once I copy them into a new basic block.However , SSA register names ( LHS of instructions ) cannot be the same within a LLVM function and hence this problem.
Is there any way to use the API to achieve this ?
As an example - seen marked "Issue" above , the "ret" instruction is returning the old "%res" value.
How can I make sure that it returns the "%res45" and "%res46" in each of the destination basic blocks?
I am trying to add support for new intrinsics in Julia. For this I use the llvmcall fork. However, when using this in a Julia function, I always encounter the following problem:
declare function:
julia> function ptx_test(a,b,c)
idx = Base.llvmcall("""%1 = tail call i32 #llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
ret i32 %1""", Int32, ())
c[idx] = a[idx] + b[idx]
return nothing
end
ptx_test (generic function with 1 method)
retrieve llvm IR of this function:
julia> code_llvm(ptx_test, (Array{Int32,1},Array{Int32,1},Array{Int32,1}))
PTX function found: ptx_test
ERROR: error compiling ptx_test: Failed to parse LLVM Assembly:
julia: <string>:3:20: error: use of undefined value '#llvm.nvvm.read.ptx.sreg.tid.x'
%1 = tail call i32 #llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
^
in _dump_function at reflection.jl:132
in code_llvm at reflection.jl:139
However, if I execute the same code_llvm command again directly after this, It works (correct IR is returned). How can I avoid this error when compiling for the first time?
My goal is to do something simple in LLVM. I want to, using the C library function getchar, define an LLVM function that reads an input from the commandline. Here is my algorithm in pseudocode:
getInt:
get a character, set the value to VAL
check if VAL is '-'
if yes then set SGN to -1 and set VAL to the next character else set SGN to 1
set NV = to the next char minus 48
while (NV >= 0) // 48 is the first ASCII character that represents a number
set VAL = VAL*10
set VAL = VAL + NV
set NV to the next char minus 48
return SGN*VAL
So now, the LLVM code I come up with for doing this is in my head the most straightforward way to translate the above into LLVM IR. However, I get the error
"PHI nodes not grouped at the top of the basic block." If I move some things around to fix this error, I get errors about dominance. Below is the LLVM IR code that gives me the PHI nodes error. I believe I am misunderstanding something basic about LLVM IR, so any help you can give is super appreciated.
define i32 #getIntLoop() {
_L1:
%0 = call i32 #getchar()
%1 = phi i32 [ %0, %_L1 ], [ %3, %_L2 ], [ %8, %_L4 ]
%2 = icmp eq i32 %1, 45
br i1 %2, label %_L2, label %_L5
_L2: ; preds = %_L1
%3 = call i32 #getchar()
br label %_L3
_L3: ; preds = %_L4, %_L2
%4 = call i32 #getchar()
%5 = icmp slt i32 %4, 40
br i1 %5, label %_L5, label %_L4
_L4: ; preds = %_L3
%6 = sub i32 %4, 48
%7 = mul i32 %1, 10
%8 = add i32 %6, %7
br label %_L3
_L5: ; preds = %_L3, %_L1
br i1 %2, label %_L6, label %_L7
_L6: ; preds = %_L5
%9 = mul i32 -1, %1
ret i32 %9
_L7: ; preds = %_L5
ret i32 %1
}
You're getting a very clear error, though. According to the LLVM IR language reference:
There must be no non-phi instructions between the start of a basic
block and the PHI instructions: i.e. PHI instructions must be first in
a basic block.
You have a phi in L1 which violates this.
Why does it have %_L1 as one of its sources? There are no jumps to %_L1 anywhere else. I think you should first understand how phi works, possibly by compiling small pieces of C code into LLVM IR with Clang and see what gets generated.
Put simply, a phi is needed to have consistency in SSA form while being able to assign one of several values into the same register. Make sure you read about SSA - it explains Phi node as well. And additional good resource is the LLVM tutorial which you should go through. In particular, part 5 covers Phis. As suggested above, running small pieces of C through Clang is a great way to understand how things work. This is in no way "hacky" - it's the scientific method! You read the theory, think hard about it, form hypotheses about how things work and then verify those hypotheses by running Clang and seeing what it generates for real-life control flow.
With LLVM I am trying to find out if an Instruction is present within flow control (if/switch/for) etc and I have to do this at the IR level. A pseudo-code is something like this as below.
if cond
inst
endif
I am looking at the SCC of the function but I am not sure how to deduce for sure if an instruction does exist within a flow control or not.
Taking the example from the Kaleidoscope example for this IR.
declare double #foo()
declare double #bar()
define double #baz(double %x) {
entry:
%ifcond = fcmp one double %x, 0.000000e+00
%0 = call double #foo()
br i1 %ifcond, label %then, label %else
then: ; preds = %entry
%calltmp = call double #foo()
br label %ifcont
else: ; preds = %entry
%calltmp1 = call double #bar()
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
%1 = call double #foo()
ret double %iftmp
}
So in the above IR, lets say I want to find out all the calls to the function foo. So in the entry block we have one call with %0 and one in the then: block we have another call to foo and the last one in the ifcont: block.
So the question is that although the call in the then: block falls in the code generated from if block, how do I deduce that ? i.e. entry block & ifcont block will be executed, however the then: block won't be necessarily executed depending on the condition.
Could someone give me some pointers ?
Thanks
Edit: Giving some more thought, Dominator trees might help in determining this but I don't have an algorithm for this yet.
Here's a definition of instruction post-domination from Wikipedia:
Analogous to the definition of dominance above, a node z is said to
post-dominate a node n if all paths to the exit node of the graph
starting at n must go through z.
It seems to me that in your case you're looking for calls that post-dominate the first instruction in the function. Such calls, by definition of post-domination, must be reached on every path from the first instruction. Is this what you need?
You can run the DominatorTree pass which seems to support post-domination analysis.