[llvm-c] Add LLVMGetValueKind.

Patch by Nicole Mazzuca <npmazzuca@gmail.com>.

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

llvm-svn: 265608
This commit is contained in:
Peter Zotov 2016-04-06 22:21:29 +00:00
parent a6534d0295
commit 4cb25f12c5
3 changed files with 118 additions and 53 deletions

View File

@ -247,6 +247,37 @@ typedef enum {
LLVMX86FastcallCallConv = 65
} LLVMCallConv;
typedef enum {
LLVMArgumentValueKind,
LLVMBasicBlockValueKind,
LLVMMemoryUseValueKind,
LLVMMemoryDefValueKind,
LLVMMemoryPhiValueKind,
LLVMFunctionValueKind,
LLVMGlobalAliasValueKind,
LLVMGlobalVariableValueKind,
LLVMBlockAddressValueKind,
LLVMConstantExprValueKind,
LLVMConstantArrayValueKind,
LLVMConstantStructValueKind,
LLVMConstantVectorValueKind,
LLVMUndefValueValueKind,
LLVMConstantAggregateZeroValueKind,
LLVMConstantDataArrayValueKind,
LLVMConstantDataVectorValueKind,
LLVMConstantIntValueKind,
LLVMConstantFPValueKind,
LLVMConstantPointerNullValueKind,
LLVMConstantTokenNoneValueKind,
LLVMMetadataAsValueValueKind,
LLVMInlineAsmValueKind,
LLVMInstructionValueKind,
} LLVMValueKind;
typedef enum {
LLVMIntEQ = 32, /**< equal */
LLVMIntNE, /**< not equal */
@ -1190,6 +1221,13 @@ LLVMTypeRef LLVMX86MMXType(void);
*/
LLVMTypeRef LLVMTypeOf(LLVMValueRef Val);
/**
* Obtain the enumerated type of a Value instance.
*
* @see llvm::Value::getValueID()
*/
LLVMValueKind LLVMGetValueKind(LLVMValueRef Val);
/**
* Obtain the string name of a value.
*

View File

@ -550,6 +550,17 @@ LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) {
return wrap(unwrap(Val)->getType());
}
LLVMValueKind LLVMGetValueKind(LLVMValueRef Val) {
switch(unwrap(Val)->getValueID()) {
#define HANDLE_VALUE(Name) \
case Value::Name##Val: \
return LLVM##Name##ValueKind;
#include "llvm/IR/Value.def"
default:
return LLVMInstructionValueKind;
}
}
const char *LLVMGetValueName(LLVMValueRef Val) {
return unwrap(Val)->getName().data();
}

View File

@ -213,6 +213,7 @@ static ValueMap clone_params(LLVMValueRef Src, LLVMValueRef Dst) {
}
LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
LLVMValueRef Ret;
if (!LLVMIsAConstant(Cst))
report_fatal_error("Expected a constant");
@ -222,88 +223,97 @@ LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) {
// Try function
if (LLVMIsAFunction(Cst)) {
LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
if (Dst)
return Dst;
report_fatal_error("Could not find function");
}
if (LLVMGetValueKind(Cst) != LLVMFunctionValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
Ret = LLVMGetNamedFunction(M, Name);
if (!Ret)
report_fatal_error("Could not find function");
// Try global variable
if (LLVMIsAGlobalVariable(Cst)) {
LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
if (Dst)
return Dst;
report_fatal_error("Could not find function");
} else if (LLVMIsAGlobalVariable(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMGlobalVariableValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
Ret = LLVMGetNamedGlobal(M, Name);
if (!Ret)
report_fatal_error("Could not find function");
} else {
fprintf(stderr, "Could not find @%s\n", Name);
exit(-1);
}
fprintf(stderr, "Could not find @%s\n", Name);
exit(-1);
}
// Try integer literal
if (LLVMIsAConstantInt(Cst))
return LLVMConstInt(TypeCloner(M).Clone(Cst),
LLVMConstIntGetZExtValue(Cst), false);
} else if (LLVMIsAConstantInt(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantIntValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
Ret = LLVMConstInt(TypeCloner(M).Clone(Cst), LLVMConstIntGetZExtValue(Cst),
false);
// Try zeroinitializer
if (LLVMIsAConstantAggregateZero(Cst))
return LLVMConstNull(TypeCloner(M).Clone(Cst));
} else if (LLVMIsAConstantAggregateZero(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantAggregateZeroValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
Ret = LLVMConstNull(TypeCloner(M).Clone(Cst));
// Try constant array
if (LLVMIsAConstantArray(Cst)) {
} else if (LLVMIsAConstantArray(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantArrayValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
unsigned EltCount = LLVMGetArrayLength(Ty);
SmallVector<LLVMValueRef, 8> Elts;
for (unsigned i = 0; i < EltCount; i++)
Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
}
Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
// Try contant data array
if (LLVMIsAConstantDataArray(Cst)) {
} else if (LLVMIsAConstantDataArray(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantDataArrayValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
unsigned EltCount = LLVMGetArrayLength(Ty);
SmallVector<LLVMValueRef, 8> Elts;
for (unsigned i = 0; i < EltCount; i++)
Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M));
return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
}
Ret = LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
// Try constant struct
if (LLVMIsAConstantStruct(Cst)) {
} else if (LLVMIsAConstantStruct(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantStructValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
unsigned EltCount = LLVMCountStructElementTypes(Ty);
SmallVector<LLVMValueRef, 8> Elts;
for (unsigned i = 0; i < EltCount; i++)
Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
if (LLVMGetStructName(Ty))
return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
EltCount, LLVMIsPackedStruct(Ty));
}
Ret = LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
else
Ret = LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
EltCount, LLVMIsPackedStruct(Ty));
// Try undef
if (LLVMIsUndef(Cst))
return LLVMGetUndef(TypeCloner(M).Clone(Cst));
} else if (LLVMIsUndef(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMUndefValueValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
Ret = LLVMGetUndef(TypeCloner(M).Clone(Cst));
// Try float literal
if (LLVMIsAConstantFP(Cst))
} else if (LLVMIsAConstantFP(Cst)) {
if (LLVMGetValueKind(Cst) != LLVMConstantFPValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
report_fatal_error("ConstantFP is not supported");
// This kind of constant is not supported
if (!LLVMIsAConstantExpr(Cst))
} else if (!LLVMIsAConstantExpr(Cst)) {
report_fatal_error("Expected a constant expression");
// At this point, it must be a constant expression
LLVMOpcode Op = LLVMGetConstOpcode(Cst);
switch(Op) {
case LLVMBitCast:
return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M),
TypeCloner(M).Clone(Cst));
default:
fprintf(stderr, "%d is not a supported opcode\n", Op);
exit(-1);
// At this point, it must be a constant expression, and thus, an opcode
} else {
LLVMOpcode Op = LLVMGetConstOpcode(Cst);
switch(Op) {
case LLVMBitCast:
return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M),
TypeCloner(M).Clone(Cst));
default:
fprintf(stderr, "%d is not a supported opcode\n", Op);
exit(-1);
}
}
if (LLVMGetValueKind(Ret) != LLVMGetValueKind(Cst)) {
report_fatal_error(
"The ValueKind of Ret is not equal to the ValueKind of Cst");
}
return Ret;
}
struct FunCloner {
@ -338,6 +348,9 @@ struct FunCloner {
if (!LLVMIsAInstruction(Src))
report_fatal_error("Expected an instruction");
if (LLVMGetValueKind(Src) != LLVMInstructionValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
auto Ctx = LLVMGetModuleContext(M);
auto Builder = LLVMCreateBuilderInContext(Ctx);
auto BB = DeclareBB(LLVMGetInstructionParent(Src));
@ -352,6 +365,9 @@ struct FunCloner {
if (!LLVMIsAInstruction(Src))
report_fatal_error("Expected an instruction");
if (LLVMGetValueKind(Src) != LLVMInstructionValueKind)
report_fatal_error("LLVMGetValueKind returned incorrect type");
// Check if this is something we already computed.
{
auto i = VMap.find(Src);