mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Add support for phi nodes in the LLVM C API test
Summary: This required to add binding to Instruction::removeFromParent so that instruction can be forward declared and then moved at the right place. Reviewers: bogner, chandlerc, echristo, dblaikie, joker.eph, Wallbraker Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D17057 llvm-svn: 260597
This commit is contained in:
parent
8ce2daeb5d
commit
acebdda8cc
@ -2328,6 +2328,16 @@ LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
|
||||
*/
|
||||
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
|
||||
|
||||
/**
|
||||
* Remove and delete an instruction.
|
||||
*
|
||||
* The instruction specified is removed from its containing building
|
||||
* block but is kept alive.
|
||||
*
|
||||
* @see llvm::Instruction::removeFromParent()
|
||||
*/
|
||||
void LLVMInstructionRemoveFromParent(LLVMValueRef Inst);
|
||||
|
||||
/**
|
||||
* Remove and delete an instruction.
|
||||
*
|
||||
|
@ -2005,6 +2005,10 @@ LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) {
|
||||
return wrap(&*--I);
|
||||
}
|
||||
|
||||
void LLVMInstructionRemoveFromParent(LLVMValueRef Inst) {
|
||||
unwrap<Instruction>(Inst)->removeFromParent();
|
||||
}
|
||||
|
||||
void LLVMInstructionEraseFromParent(LLVMValueRef Inst) {
|
||||
unwrap<Instruction>(Inst)->eraseFromParent();
|
||||
}
|
||||
|
@ -90,3 +90,19 @@ next8:
|
||||
next9:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define i32 @loop(i32 %i) {
|
||||
br label %cond
|
||||
cond:
|
||||
%c = phi i32 [ %i, %0 ], [ %j, %do ]
|
||||
%p = phi i32 [ %r, %do ], [ 789, %0 ]
|
||||
%1 = icmp eq i32 %c, 0
|
||||
br i1 %1, label %do, label %done
|
||||
do:
|
||||
%2 = sub i32 %p, 23
|
||||
%j = sub i32 %i, 1
|
||||
%r = mul i32 %2, 3
|
||||
br label %cond
|
||||
done:
|
||||
ret i32 %p
|
||||
}
|
||||
|
@ -206,24 +206,20 @@ struct FunCloner {
|
||||
}
|
||||
|
||||
// Function argument should always be in the map already.
|
||||
if (LLVMIsAArgument(Src)) {
|
||||
auto i = VMap.find(Src);
|
||||
if (i != VMap.end())
|
||||
return i->second;
|
||||
}
|
||||
auto i = VMap.find(Src);
|
||||
if (i != VMap.end())
|
||||
return i->second;
|
||||
|
||||
if (LLVMIsAInstruction(Src)) {
|
||||
auto Ctx = LLVMGetModuleContext(M);
|
||||
auto Builder = LLVMCreateBuilderInContext(Ctx);
|
||||
auto BB = DeclareBB(LLVMGetInstructionParent(Src));
|
||||
LLVMPositionBuilderAtEnd(Builder, BB);
|
||||
auto Dst = CloneInstruction(Src, Builder);
|
||||
LLVMDisposeBuilder(Builder);
|
||||
return Dst;
|
||||
}
|
||||
if (!LLVMIsAInstruction(Src))
|
||||
report_fatal_error("Expected an instruction");
|
||||
|
||||
fprintf(stderr, "Could not determine the type of %s\n", Name);
|
||||
exit(-1);
|
||||
auto Ctx = LLVMGetModuleContext(M);
|
||||
auto Builder = LLVMCreateBuilderInContext(Ctx);
|
||||
auto BB = DeclareBB(LLVMGetInstructionParent(Src));
|
||||
LLVMPositionBuilderAtEnd(Builder, BB);
|
||||
auto Dst = CloneInstruction(Src, Builder);
|
||||
LLVMDisposeBuilder(Builder);
|
||||
return Dst;
|
||||
}
|
||||
|
||||
LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
|
||||
@ -234,8 +230,15 @@ struct FunCloner {
|
||||
// Check if this is something we already computed.
|
||||
{
|
||||
auto i = VMap.find(Src);
|
||||
if (i != VMap.end())
|
||||
return i->second;
|
||||
if (i != VMap.end()) {
|
||||
// If we have a hit, it means we already generated the instruction
|
||||
// as a dependancy to somethign else. We need to make sure
|
||||
// it is ordered properly.
|
||||
auto I = i->second;
|
||||
LLVMInstructionRemoveFromParent(I);
|
||||
LLVMInsertIntoBuilderWithName(Builder, I, Name);
|
||||
return I;
|
||||
}
|
||||
}
|
||||
|
||||
// We tried everything, it must be an instruction
|
||||
@ -365,6 +368,22 @@ struct FunCloner {
|
||||
Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
|
||||
break;
|
||||
}
|
||||
case LLVMPHI: {
|
||||
// We need to agressively set things here because of loops.
|
||||
VMap[Src] = Dst = LLVMBuildPhi(Builder, CloneType(Src), Name);
|
||||
|
||||
SmallVector<LLVMValueRef, 8> Values;
|
||||
SmallVector<LLVMBasicBlockRef, 8> Blocks;
|
||||
|
||||
unsigned IncomingCount = LLVMCountIncoming(Src);
|
||||
for (unsigned i = 0; i < IncomingCount; ++i) {
|
||||
Blocks.push_back(DeclareBB(LLVMGetIncomingBlock(Src, i)));
|
||||
Values.push_back(CloneValue(LLVMGetIncomingValue(Src, i)));
|
||||
}
|
||||
|
||||
LLVMAddIncoming(Dst, Values.data(), Blocks.data(), IncomingCount);
|
||||
return Dst;
|
||||
}
|
||||
case LLVMCall: {
|
||||
SmallVector<LLVMValueRef, 8> Args;
|
||||
int ArgCount = LLVMGetNumArgOperands(Src);
|
||||
|
Loading…
x
Reference in New Issue
Block a user