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);
|
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.
|
* Remove and delete an instruction.
|
||||||
*
|
*
|
||||||
|
@ -2005,6 +2005,10 @@ LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) {
|
|||||||
return wrap(&*--I);
|
return wrap(&*--I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLVMInstructionRemoveFromParent(LLVMValueRef Inst) {
|
||||||
|
unwrap<Instruction>(Inst)->removeFromParent();
|
||||||
|
}
|
||||||
|
|
||||||
void LLVMInstructionEraseFromParent(LLVMValueRef Inst) {
|
void LLVMInstructionEraseFromParent(LLVMValueRef Inst) {
|
||||||
unwrap<Instruction>(Inst)->eraseFromParent();
|
unwrap<Instruction>(Inst)->eraseFromParent();
|
||||||
}
|
}
|
||||||
|
@ -90,3 +90,19 @@ next8:
|
|||||||
next9:
|
next9:
|
||||||
ret i32 0
|
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.
|
// Function argument should always be in the map already.
|
||||||
if (LLVMIsAArgument(Src)) {
|
auto i = VMap.find(Src);
|
||||||
auto i = VMap.find(Src);
|
if (i != VMap.end())
|
||||||
if (i != VMap.end())
|
return i->second;
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LLVMIsAInstruction(Src)) {
|
if (!LLVMIsAInstruction(Src))
|
||||||
auto Ctx = LLVMGetModuleContext(M);
|
report_fatal_error("Expected an instruction");
|
||||||
auto Builder = LLVMCreateBuilderInContext(Ctx);
|
|
||||||
auto BB = DeclareBB(LLVMGetInstructionParent(Src));
|
|
||||||
LLVMPositionBuilderAtEnd(Builder, BB);
|
|
||||||
auto Dst = CloneInstruction(Src, Builder);
|
|
||||||
LLVMDisposeBuilder(Builder);
|
|
||||||
return Dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "Could not determine the type of %s\n", Name);
|
auto Ctx = LLVMGetModuleContext(M);
|
||||||
exit(-1);
|
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) {
|
LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
|
||||||
@ -234,8 +230,15 @@ struct FunCloner {
|
|||||||
// Check if this is something we already computed.
|
// Check if this is something we already computed.
|
||||||
{
|
{
|
||||||
auto i = VMap.find(Src);
|
auto i = VMap.find(Src);
|
||||||
if (i != VMap.end())
|
if (i != VMap.end()) {
|
||||||
return i->second;
|
// 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
|
// We tried everything, it must be an instruction
|
||||||
@ -365,6 +368,22 @@ struct FunCloner {
|
|||||||
Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
|
Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
|
||||||
break;
|
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: {
|
case LLVMCall: {
|
||||||
SmallVector<LLVMValueRef, 8> Args;
|
SmallVector<LLVMValueRef, 8> Args;
|
||||||
int ArgCount = LLVMGetNumArgOperands(Src);
|
int ArgCount = LLVMGetNumArgOperands(Src);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user