1
0
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:
Amaury Sechet 2016-02-11 21:37:54 +00:00
parent 8ce2daeb5d
commit acebdda8cc
4 changed files with 67 additions and 18 deletions

View File

@ -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.
* *

View File

@ -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();
} }

View File

@ -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
}

View File

@ -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);