[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 LLVMX86FastcallCallConv = 65
} LLVMCallConv; } 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 { typedef enum {
LLVMIntEQ = 32, /**< equal */ LLVMIntEQ = 32, /**< equal */
LLVMIntNE, /**< not equal */ LLVMIntNE, /**< not equal */
@ -1190,6 +1221,13 @@ LLVMTypeRef LLVMX86MMXType(void);
*/ */
LLVMTypeRef LLVMTypeOf(LLVMValueRef Val); 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. * Obtain the string name of a value.
* *

View File

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