1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Split clone value and instruction in the echo C API test

Summary: This is a bit of refactoring required to be able to generate instruction in forward basic block. This, for instance, is a requirement for phi in loops.

Reviewers: bogner, chandlerc, echristo, dblaikie, joker.eph, Wallbraker

Differential Revision: http://reviews.llvm.org/D17050

llvm-svn: 260324
This commit is contained in:
Amaury Sechet 2016-02-09 23:41:20 +00:00
parent 352aef6336
commit dfe90fdcf0

View File

@ -125,46 +125,26 @@ static LLVMTypeRef clone_type(LLVMTypeRef Src, LLVMContextRef Ctx) {
exit(-1); exit(-1);
} }
static LLVMValueRef clone_literal(LLVMValueRef Src, LLVMContextRef Ctx) {
LLVMTypeRef Ty = clone_type(LLVMTypeOf(Src), Ctx);
LLVMTypeKind Kind = LLVMGetTypeKind(Ty);
switch (Kind) {
case LLVMIntegerTypeKind:
return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
default:
break;
}
fprintf(stderr, "%d is not a supported constant typekind\n", Kind);
exit(-1);
}
static LLVMModuleRef get_module(LLVMBuilderRef Builder) {
LLVMBasicBlockRef BB = LLVMGetInsertBlock(Builder);
LLVMValueRef Fn = LLVMGetBasicBlockParent(BB);
return LLVMGetGlobalParent(Fn);
}
static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst); static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst);
struct FunCloner { struct FunCloner {
LLVMValueRef Fun; LLVMValueRef Fun;
LLVMModuleRef M;
LLVMContextRef Ctx;
ValueMap VMap; ValueMap VMap;
BasicBlockMap BBMap; BasicBlockMap BBMap;
FunCloner(LLVMValueRef Src, LLVMValueRef Dst) FunCloner(LLVMValueRef Src, LLVMValueRef Dst)
: Fun(Dst), VMap(clone_params(Src, Dst)) {} : Fun(Dst), M(LLVMGetGlobalParent(Fun)), Ctx(LLVMGetModuleContext(M)),
VMap(clone_params(Src, Dst)) {}
// Try to clone everything in the llvm::Value hierarchy. // Try to clone everything in the llvm::Value hierarchy.
LLVMValueRef CloneValue(LLVMValueRef Src, LLVMBuilderRef Builder) { LLVMValueRef CloneValue(LLVMValueRef Src) {
const char *Name = LLVMGetValueName(Src); const char *Name = LLVMGetValueName(Src);
// First, the value may be constant. // First, the value may be constant.
if (LLVMIsAConstant(Src)) { if (LLVMIsAConstant(Src)) {
LLVMModuleRef M = get_module(Builder);
// Maybe it is a symbol // Maybe it is a symbol
if (LLVMIsAGlobalValue(Src)) { if (LLVMIsAGlobalValue(Src)) {
// Try function // Try function
@ -182,17 +162,44 @@ struct FunCloner {
} }
// Try literal // Try literal
LLVMContextRef Ctx = LLVMGetModuleContext(M); if (LLVMIsAConstantInt(Src)) {
return clone_literal(Src, Ctx); LLVMTypeRef Ty = clone_type(LLVMTypeOf(Src), Ctx);
return LLVMConstInt(Ty, LLVMConstIntGetZExtValue(Src), false);
}
// Try undef
if (LLVMIsUndef(Src))
return LLVMGetUndef(clone_type(LLVMTypeOf(Src), Ctx));
// This kind of constant is not supported.
report_fatal_error("Unsupported contant type");
} }
// Try undef // Function argument should always be in the map already.
if (LLVMIsUndef(Src)) { if (LLVMIsAArgument(Src)) {
LLVMContextRef Ctx = LLVMGetModuleContext(get_module(Builder)); auto i = VMap.find(Src);
LLVMTypeRef Ty = clone_type(LLVMTypeOf(Src), Ctx); if (i != VMap.end())
return LLVMGetUndef(Ty); return i->second;
} }
if (LLVMIsAInstruction(Src)) {
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);
exit(-1);
}
LLVMValueRef CloneInstruction(LLVMValueRef Src, LLVMBuilderRef Builder) {
const char *Name = LLVMGetValueName(Src);
if (!LLVMIsAInstruction(Src))
report_fatal_error("Expected an instruction");
// 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);
@ -211,8 +218,7 @@ struct FunCloner {
if (OpCount == 0) if (OpCount == 0)
Dst = LLVMBuildRetVoid(Builder); Dst = LLVMBuildRetVoid(Builder);
else else
Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0), Dst = LLVMBuildRet(Builder, CloneValue(LLVMGetOperand(Src, 0)));
Builder));
break; break;
} }
case LLVMBr: { case LLVMBr: {
@ -239,102 +245,101 @@ struct FunCloner {
Dst = LLVMBuildUnreachable(Builder); Dst = LLVMBuildUnreachable(Builder);
break; break;
case LLVMAdd: { case LLVMAdd: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildAdd(Builder, LHS, RHS, Name); Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMSub: { case LLVMSub: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildSub(Builder, LHS, RHS, Name); Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMMul: { case LLVMMul: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildMul(Builder, LHS, RHS, Name); Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMUDiv: { case LLVMUDiv: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name); Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMSDiv: { case LLVMSDiv: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name); Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMURem: { case LLVMURem: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildURem(Builder, LHS, RHS, Name); Dst = LLVMBuildURem(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMSRem: { case LLVMSRem: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildSRem(Builder, LHS, RHS, Name); Dst = LLVMBuildSRem(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMShl: { case LLVMShl: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildShl(Builder, LHS, RHS, Name); Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMLShr: { case LLVMLShr: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildLShr(Builder, LHS, RHS, Name); Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMAShr: { case LLVMAShr: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildAShr(Builder, LHS, RHS, Name); Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMAnd: { case LLVMAnd: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildAnd(Builder, LHS, RHS, Name); Dst = LLVMBuildAnd(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMOr: { case LLVMOr: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildOr(Builder, LHS, RHS, Name); Dst = LLVMBuildOr(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMXor: { case LLVMXor: {
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildXor(Builder, LHS, RHS, Name); Dst = LLVMBuildXor(Builder, LHS, RHS, Name);
break; break;
} }
case LLVMAlloca: { case LLVMAlloca: {
LLVMContextRef Ctx = LLVMGetModuleContext(get_module(Builder));
LLVMTypeRef Ty = clone_type(LLVMGetAllocatedType(Src), Ctx); LLVMTypeRef Ty = clone_type(LLVMGetAllocatedType(Src), Ctx);
Dst = LLVMBuildAlloca(Builder, Ty, Name); Dst = LLVMBuildAlloca(Builder, Ty, Name);
break; break;
} }
case LLVMICmp: { case LLVMICmp: {
LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src); LLVMIntPredicate Pred = LLVMGetICmpPredicate(Src);
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0), Builder); LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1), Builder); LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name); Dst = LLVMBuildICmp(Builder, Pred, LHS, RHS, Name);
break; break;
} }
case LLVMCall: { case LLVMCall: {
int ArgCount = LLVMGetNumOperands(Src) - 1;
SmallVector<LLVMValueRef, 8> Args; SmallVector<LLVMValueRef, 8> Args;
int ArgCount = LLVMGetNumOperands(Src) - 1;
for (int i = 0; i < ArgCount; i++) for (int i = 0; i < ArgCount; i++)
Args.push_back(CloneValue(LLVMGetOperand(Src, i), Builder)); Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
LLVMValueRef Fn = CloneValue(LLVMGetOperand(Src, ArgCount), Builder); LLVMValueRef Fn = CloneValue(LLVMGetOperand(Src, ArgCount));
Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name); Dst = LLVMBuildCall(Builder, Fn, Args.data(), ArgCount, Name);
break; break;
} }
@ -363,7 +368,7 @@ struct FunCloner {
LLVMValueRef V = LLVMBasicBlockAsValue(Src); LLVMValueRef V = LLVMBasicBlockAsValue(Src);
if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src) if (!LLVMValueIsBasicBlock(V) || LLVMValueAsBasicBlock(V) != Src)
report_fatal_error("Basic block is not a basic block\n"); report_fatal_error("Basic block is not a basic block");
const char *VName = LLVMGetValueName(V); const char *VName = LLVMGetValueName(V);
if (Name != VName) if (Name != VName)
@ -393,14 +398,13 @@ struct FunCloner {
return BB; return BB;
} }
LLVMContextRef Ctx = LLVMGetModuleContext(LLVMGetGlobalParent(Fun));
LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx); LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
LLVMPositionBuilderAtEnd(Builder, BB); LLVMPositionBuilderAtEnd(Builder, BB);
LLVMValueRef Cur = First; LLVMValueRef Cur = First;
LLVMValueRef Next = nullptr; LLVMValueRef Next = nullptr;
while(true) { while(true) {
CloneValue(Cur, Builder); CloneInstruction(Cur, Builder);
Next = LLVMGetNextInstruction(Cur); Next = LLVMGetNextInstruction(Cur);
if (Next == nullptr) { if (Next == nullptr) {
if (Cur != Last) { if (Cur != Last) {
@ -540,17 +544,17 @@ static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
return VMap; return VMap;
} }
static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef Dst) { static LLVMValueRef clone_function(LLVMValueRef Src, LLVMModuleRef M) {
const char *Name = LLVMGetValueName(Src); const char *Name = LLVMGetValueName(Src);
LLVMValueRef Fun = LLVMGetNamedFunction(Dst, Name); LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
if (Fun != nullptr) if (Fun != nullptr)
return Fun; return Fun;
LLVMTypeRef SrcTy = LLVMTypeOf(Src); LLVMTypeRef SrcTy = LLVMTypeOf(Src);
LLVMTypeRef DstTy = clone_type(SrcTy, LLVMGetModuleContext(Dst)); LLVMTypeRef DstTy = clone_type(SrcTy, LLVMGetModuleContext(M));
LLVMTypeRef FunTy = LLVMGetElementType(DstTy); LLVMTypeRef FunTy = LLVMGetElementType(DstTy);
Fun = LLVMAddFunction(Dst, Name, FunTy); Fun = LLVMAddFunction(M, Name, FunTy);
FunCloner FC(Src, Fun); FunCloner FC(Src, Fun);
FC.CloneBBs(Src); FC.CloneBBs(Src);