mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 01:15:32 +00:00
Make structs and arrays first-class types, and add assembly
and bitcode support for the extractvalue and insertvalue instructions and constant expressions. Note that this does not yet include CodeGen support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51468 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8f8e269270
commit
e4977cf750
@ -125,7 +125,9 @@ namespace bitc {
|
|||||||
CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval]
|
CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval]
|
||||||
CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
|
CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
|
||||||
CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
|
CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
|
||||||
CST_CODE_INLINEASM = 18 // INLINEASM: [sideeffect,asmstr,conststr]
|
CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr]
|
||||||
|
CST_CODE_CE_EXTRACTVAL = 19, // CE_EXTRACTVAL: [n x operands]
|
||||||
|
CST_CODE_CE_INSERTVAL = 20 // CE_INSERTVAL: [n x operands]
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CastOpcodes - These are values used in the bitcode files to encode which
|
/// CastOpcodes - These are values used in the bitcode files to encode which
|
||||||
@ -202,7 +204,9 @@ namespace bitc {
|
|||||||
// this is so information only available in the pointer type (e.g. address
|
// this is so information only available in the pointer type (e.g. address
|
||||||
// spaces) is retained.
|
// spaces) is retained.
|
||||||
FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol]
|
FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol]
|
||||||
FUNC_CODE_INST_GETRESULT = 25 // GETRESULT: [ty, opval, n]
|
FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n]
|
||||||
|
FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
|
||||||
|
FUNC_CODE_INST_INSERTVAL = 27 // INSERTVAL: [n x operands]
|
||||||
};
|
};
|
||||||
} // End bitc namespace
|
} // End bitc namespace
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -216,8 +216,8 @@ public:
|
|||||||
/// is a valid type for a Value.
|
/// is a valid type for a Value.
|
||||||
///
|
///
|
||||||
inline bool isFirstClassType() const {
|
inline bool isFirstClassType() const {
|
||||||
// Coming soon: first-class struct and array types...
|
return isSingleValueType() ||
|
||||||
return isSingleValueType();
|
ID == StructTyID || ID == ArrayTyID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isSingleValueType - Return true if the type is a valid type for a
|
/// isSingleValueType - Return true if the type is a valid type for a
|
||||||
|
@ -605,6 +605,8 @@ int LLLexer::LexIdentifier() {
|
|||||||
INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT);
|
INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT);
|
||||||
INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR);
|
INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR);
|
||||||
INSTKEYWORD("getresult", OtherOpVal, GetResult, GETRESULT);
|
INSTKEYWORD("getresult", OtherOpVal, GetResult, GETRESULT);
|
||||||
|
INSTKEYWORD("extractvalue", OtherOpVal, ExtractValue, EXTRACTVALUE);
|
||||||
|
INSTKEYWORD("insertvalue", OtherOpVal, InsertValue, INSERTVALUE);
|
||||||
#undef INSTKEYWORD
|
#undef INSTKEYWORD
|
||||||
|
|
||||||
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
|
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -175,21 +175,23 @@
|
|||||||
INSERTELEMENT = 391,
|
INSERTELEMENT = 391,
|
||||||
SHUFFLEVECTOR = 392,
|
SHUFFLEVECTOR = 392,
|
||||||
GETRESULT = 393,
|
GETRESULT = 393,
|
||||||
SIGNEXT = 394,
|
EXTRACTVALUE = 394,
|
||||||
ZEROEXT = 395,
|
INSERTVALUE = 395,
|
||||||
NORETURN = 396,
|
SIGNEXT = 396,
|
||||||
INREG = 397,
|
ZEROEXT = 397,
|
||||||
SRET = 398,
|
NORETURN = 398,
|
||||||
NOUNWIND = 399,
|
INREG = 399,
|
||||||
NOALIAS = 400,
|
SRET = 400,
|
||||||
BYVAL = 401,
|
NOUNWIND = 401,
|
||||||
NEST = 402,
|
NOALIAS = 402,
|
||||||
READNONE = 403,
|
BYVAL = 403,
|
||||||
READONLY = 404,
|
NEST = 404,
|
||||||
GC = 405,
|
READNONE = 405,
|
||||||
DEFAULT = 406,
|
READONLY = 406,
|
||||||
HIDDEN = 407,
|
GC = 407,
|
||||||
PROTECTED = 408
|
DEFAULT = 408,
|
||||||
|
HIDDEN = 409,
|
||||||
|
PROTECTED = 410
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
@ -329,28 +331,30 @@
|
|||||||
#define INSERTELEMENT 391
|
#define INSERTELEMENT 391
|
||||||
#define SHUFFLEVECTOR 392
|
#define SHUFFLEVECTOR 392
|
||||||
#define GETRESULT 393
|
#define GETRESULT 393
|
||||||
#define SIGNEXT 394
|
#define EXTRACTVALUE 394
|
||||||
#define ZEROEXT 395
|
#define INSERTVALUE 395
|
||||||
#define NORETURN 396
|
#define SIGNEXT 396
|
||||||
#define INREG 397
|
#define ZEROEXT 397
|
||||||
#define SRET 398
|
#define NORETURN 398
|
||||||
#define NOUNWIND 399
|
#define INREG 399
|
||||||
#define NOALIAS 400
|
#define SRET 400
|
||||||
#define BYVAL 401
|
#define NOUNWIND 401
|
||||||
#define NEST 402
|
#define NOALIAS 402
|
||||||
#define READNONE 403
|
#define BYVAL 403
|
||||||
#define READONLY 404
|
#define NEST 404
|
||||||
#define GC 405
|
#define READNONE 405
|
||||||
#define DEFAULT 406
|
#define READONLY 406
|
||||||
#define HIDDEN 407
|
#define GC 407
|
||||||
#define PROTECTED 408
|
#define DEFAULT 408
|
||||||
|
#define HIDDEN 409
|
||||||
|
#define PROTECTED 410
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
#line 949 "/Volumes/LLVM/llvm/lib/AsmParser/llvmAsmParser.y"
|
#line 949 "/Users/gohman/LLVM/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||||
{
|
{
|
||||||
llvm::Module *ModuleVal;
|
llvm::Module *ModuleVal;
|
||||||
llvm::Function *FunctionVal;
|
llvm::Function *FunctionVal;
|
||||||
@ -398,7 +402,7 @@ typedef union YYSTYPE
|
|||||||
llvm::FCmpInst::Predicate FPredicate;
|
llvm::FCmpInst::Predicate FPredicate;
|
||||||
}
|
}
|
||||||
/* Line 1529 of yacc.c. */
|
/* Line 1529 of yacc.c. */
|
||||||
#line 402 "llvmAsmParser.tab.h"
|
#line 406 "llvmAsmParser.tab.h"
|
||||||
YYSTYPE;
|
YYSTYPE;
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
@ -475,7 +475,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
|
|||||||
if (TriggerError) return 0;
|
if (TriggerError) return 0;
|
||||||
|
|
||||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
|
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
|
||||||
GenerateError("Invalid use of a composite type");
|
GenerateError("Invalid use of a non-first-class type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,6 +1093,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
%token <OtherOpVal> PHI_TOK SELECT VAARG
|
%token <OtherOpVal> PHI_TOK SELECT VAARG
|
||||||
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
||||||
%token <OtherOpVal> GETRESULT
|
%token <OtherOpVal> GETRESULT
|
||||||
|
%token <OtherOpVal> EXTRACTVALUE INSERTVALUE
|
||||||
|
|
||||||
// Function Attributes
|
// Function Attributes
|
||||||
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
||||||
@ -1966,6 +1967,48 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
|||||||
GEN_ERROR("Invalid shufflevector operands");
|
GEN_ERROR("Invalid shufflevector operands");
|
||||||
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| EXTRACTVALUE '(' ConstVal IndexList ')' {
|
||||||
|
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||||
|
GEN_ERROR("ExtractValue requires an aggregate operand");
|
||||||
|
|
||||||
|
const Type *IdxTy =
|
||||||
|
ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
|
||||||
|
if (!IdxTy)
|
||||||
|
GEN_ERROR("Index list invalid for constant extractvalue");
|
||||||
|
|
||||||
|
SmallVector<Constant*, 8> IdxVec;
|
||||||
|
for (unsigned i = 0, e = $4->size(); i != e; ++i)
|
||||||
|
if (Constant *C = dyn_cast<Constant>((*$4)[i]))
|
||||||
|
IdxVec.push_back(C);
|
||||||
|
else
|
||||||
|
GEN_ERROR("Indices to constant extractvalue must be constants");
|
||||||
|
|
||||||
|
delete $4;
|
||||||
|
|
||||||
|
$$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
|
||||||
|
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||||
|
GEN_ERROR("InsertValue requires an aggregate operand");
|
||||||
|
|
||||||
|
const Type *IdxTy =
|
||||||
|
ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
|
||||||
|
if (IdxTy != $5->getType())
|
||||||
|
GEN_ERROR("Index list invalid for constant insertvalue");
|
||||||
|
|
||||||
|
SmallVector<Constant*, 8> IdxVec;
|
||||||
|
for (unsigned i = 0, e = $6->size(); i != e; ++i)
|
||||||
|
if (Constant *C = dyn_cast<Constant>((*$6)[i]))
|
||||||
|
IdxVec.push_back(C);
|
||||||
|
else
|
||||||
|
GEN_ERROR("Indices to constant insertvalue must be constants");
|
||||||
|
|
||||||
|
delete $6;
|
||||||
|
|
||||||
|
$$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
|
||||||
|
CHECK_FOR_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -3165,7 +3208,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = new StoreInst($3, tmpVal, $1, $7);
|
$$ = new StoreInst($3, tmpVal, $1, $7);
|
||||||
delete $5;
|
delete $5;
|
||||||
}
|
}
|
||||||
| GETRESULT Types ValueRef ',' EUINT64VAL {
|
| GETRESULT Types ValueRef ',' EUINT64VAL {
|
||||||
Value *TmpVal = getVal($2->get(), $3);
|
Value *TmpVal = getVal($2->get(), $3);
|
||||||
if (!GetResultInst::isValidOperands(TmpVal, $5))
|
if (!GetResultInst::isValidOperands(TmpVal, $5))
|
||||||
GEN_ERROR("Invalid getresult operands");
|
GEN_ERROR("Invalid getresult operands");
|
||||||
@ -3187,6 +3230,38 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
|
$$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
|
||||||
delete $2;
|
delete $2;
|
||||||
delete $4;
|
delete $4;
|
||||||
|
}
|
||||||
|
| EXTRACTVALUE Types ValueRef IndexList {
|
||||||
|
if (!UpRefs.empty())
|
||||||
|
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||||
|
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||||
|
GEN_ERROR("extractvalue insn requires an aggregate operand");
|
||||||
|
|
||||||
|
if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end()))
|
||||||
|
GEN_ERROR("Invalid extractvalue indices for type '" +
|
||||||
|
(*$2)->getDescription()+ "'");
|
||||||
|
Value* tmpVal = getVal(*$2, $3);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
$$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end());
|
||||||
|
delete $2;
|
||||||
|
delete $4;
|
||||||
|
}
|
||||||
|
| INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
|
||||||
|
if (!UpRefs.empty())
|
||||||
|
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||||
|
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||||
|
GEN_ERROR("extractvalue insn requires an aggregate operand");
|
||||||
|
|
||||||
|
if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get())
|
||||||
|
GEN_ERROR("Invalid insertvalue indices for type '" +
|
||||||
|
(*$2)->getDescription()+ "'");
|
||||||
|
Value* aggVal = getVal(*$2, $3);
|
||||||
|
Value* tmpVal = getVal(*$5, $6);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
$$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end());
|
||||||
|
delete $2;
|
||||||
|
delete $5;
|
||||||
|
delete $7;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
|
|||||||
if (TriggerError) return 0;
|
if (TriggerError) return 0;
|
||||||
|
|
||||||
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
|
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
|
||||||
GenerateError("Invalid use of a composite type");
|
GenerateError("Invalid use of a non-first-class type");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,6 +1093,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
%token <OtherOpVal> PHI_TOK SELECT VAARG
|
%token <OtherOpVal> PHI_TOK SELECT VAARG
|
||||||
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
||||||
%token <OtherOpVal> GETRESULT
|
%token <OtherOpVal> GETRESULT
|
||||||
|
%token <OtherOpVal> EXTRACTVALUE INSERTVALUE
|
||||||
|
|
||||||
// Function Attributes
|
// Function Attributes
|
||||||
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
||||||
@ -1966,6 +1967,48 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
|||||||
GEN_ERROR("Invalid shufflevector operands");
|
GEN_ERROR("Invalid shufflevector operands");
|
||||||
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| EXTRACTVALUE '(' ConstVal IndexList ')' {
|
||||||
|
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||||
|
GEN_ERROR("ExtractValue requires an aggregate operand");
|
||||||
|
|
||||||
|
const Type *IdxTy =
|
||||||
|
ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
|
||||||
|
if (!IdxTy)
|
||||||
|
GEN_ERROR("Index list invalid for constant extractvalue");
|
||||||
|
|
||||||
|
SmallVector<Constant*, 8> IdxVec;
|
||||||
|
for (unsigned i = 0, e = $4->size(); i != e; ++i)
|
||||||
|
if (Constant *C = dyn_cast<Constant>((*$4)[i]))
|
||||||
|
IdxVec.push_back(C);
|
||||||
|
else
|
||||||
|
GEN_ERROR("Indices to constant extractvalue must be constants");
|
||||||
|
|
||||||
|
delete $4;
|
||||||
|
|
||||||
|
$$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
}
|
||||||
|
| INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
|
||||||
|
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||||
|
GEN_ERROR("InsertValue requires an aggregate operand");
|
||||||
|
|
||||||
|
const Type *IdxTy =
|
||||||
|
ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
|
||||||
|
if (IdxTy != $5->getType())
|
||||||
|
GEN_ERROR("Index list invalid for constant insertvalue");
|
||||||
|
|
||||||
|
SmallVector<Constant*, 8> IdxVec;
|
||||||
|
for (unsigned i = 0, e = $6->size(); i != e; ++i)
|
||||||
|
if (Constant *C = dyn_cast<Constant>((*$6)[i]))
|
||||||
|
IdxVec.push_back(C);
|
||||||
|
else
|
||||||
|
GEN_ERROR("Indices to constant insertvalue must be constants");
|
||||||
|
|
||||||
|
delete $6;
|
||||||
|
|
||||||
|
$$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
|
||||||
|
CHECK_FOR_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2852,7 +2895,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* val2 = getVal(*$2, $5);
|
Value* val2 = getVal(*$2, $5);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = BinaryOperator::create($1, val1, val2);
|
$$ = BinaryOperator::Create($1, val1, val2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("binary operator returned null");
|
GEN_ERROR("binary operator returned null");
|
||||||
delete $2;
|
delete $2;
|
||||||
@ -2869,7 +2912,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* tmpVal2 = getVal(*$2, $5);
|
Value* tmpVal2 = getVal(*$2, $5);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = BinaryOperator::create($1, tmpVal1, tmpVal2);
|
$$ = BinaryOperator::Create($1, tmpVal1, tmpVal2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("binary operator returned null");
|
GEN_ERROR("binary operator returned null");
|
||||||
delete $2;
|
delete $2;
|
||||||
@ -2883,7 +2926,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* tmpVal2 = getVal(*$3, $6);
|
Value* tmpVal2 = getVal(*$3, $6);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
$$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("icmp operator returned null");
|
GEN_ERROR("icmp operator returned null");
|
||||||
delete $3;
|
delete $3;
|
||||||
@ -2897,7 +2940,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* tmpVal2 = getVal(*$3, $6);
|
Value* tmpVal2 = getVal(*$3, $6);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
$$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("fcmp operator returned null");
|
GEN_ERROR("fcmp operator returned null");
|
||||||
delete $3;
|
delete $3;
|
||||||
@ -2911,7 +2954,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* tmpVal2 = getVal(*$3, $6);
|
Value* tmpVal2 = getVal(*$3, $6);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
$$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("icmp operator returned null");
|
GEN_ERROR("icmp operator returned null");
|
||||||
delete $3;
|
delete $3;
|
||||||
@ -2925,7 +2968,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
Value* tmpVal2 = getVal(*$3, $6);
|
Value* tmpVal2 = getVal(*$3, $6);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
|
$$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
|
||||||
if ($$ == 0)
|
if ($$ == 0)
|
||||||
GEN_ERROR("fcmp operator returned null");
|
GEN_ERROR("fcmp operator returned null");
|
||||||
delete $3;
|
delete $3;
|
||||||
@ -2939,7 +2982,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
|||||||
GEN_ERROR("invalid cast opcode for cast from '" +
|
GEN_ERROR("invalid cast opcode for cast from '" +
|
||||||
Val->getType()->getDescription() + "' to '" +
|
Val->getType()->getDescription() + "' to '" +
|
||||||
DestTy->getDescription() + "'");
|
DestTy->getDescription() + "'");
|
||||||
$$ = CastInst::create($1, Val, DestTy);
|
$$ = CastInst::Create($1, Val, DestTy);
|
||||||
delete $4;
|
delete $4;
|
||||||
}
|
}
|
||||||
| SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
|
| SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
|
||||||
@ -3165,7 +3208,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = new StoreInst($3, tmpVal, $1, $7);
|
$$ = new StoreInst($3, tmpVal, $1, $7);
|
||||||
delete $5;
|
delete $5;
|
||||||
}
|
}
|
||||||
| GETRESULT Types ValueRef ',' EUINT64VAL {
|
| GETRESULT Types ValueRef ',' EUINT64VAL {
|
||||||
Value *TmpVal = getVal($2->get(), $3);
|
Value *TmpVal = getVal($2->get(), $3);
|
||||||
if (!GetResultInst::isValidOperands(TmpVal, $5))
|
if (!GetResultInst::isValidOperands(TmpVal, $5))
|
||||||
GEN_ERROR("Invalid getresult operands");
|
GEN_ERROR("Invalid getresult operands");
|
||||||
@ -3187,6 +3230,38 @@ MemoryInst : MALLOC Types OptCAlign {
|
|||||||
$$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
|
$$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
|
||||||
delete $2;
|
delete $2;
|
||||||
delete $4;
|
delete $4;
|
||||||
|
}
|
||||||
|
| EXTRACTVALUE Types ValueRef IndexList {
|
||||||
|
if (!UpRefs.empty())
|
||||||
|
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||||
|
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||||
|
GEN_ERROR("extractvalue insn requires an aggregate operand");
|
||||||
|
|
||||||
|
if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end()))
|
||||||
|
GEN_ERROR("Invalid extractvalue indices for type '" +
|
||||||
|
(*$2)->getDescription()+ "'");
|
||||||
|
Value* tmpVal = getVal(*$2, $3);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
$$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end());
|
||||||
|
delete $2;
|
||||||
|
delete $4;
|
||||||
|
}
|
||||||
|
| INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
|
||||||
|
if (!UpRefs.empty())
|
||||||
|
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||||
|
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||||
|
GEN_ERROR("extractvalue insn requires an aggregate operand");
|
||||||
|
|
||||||
|
if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get())
|
||||||
|
GEN_ERROR("Invalid insertvalue indices for type '" +
|
||||||
|
(*$2)->getDescription()+ "'");
|
||||||
|
Value* aggVal = getVal(*$2, $3);
|
||||||
|
Value* tmpVal = getVal(*$5, $6);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
$$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end());
|
||||||
|
delete $2;
|
||||||
|
delete $5;
|
||||||
|
delete $7;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -770,6 +770,29 @@ bool BitcodeReader::ParseConstants() {
|
|||||||
V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
|
V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case bitc::CST_CODE_CE_EXTRACTVAL: { // CE_EXTRACTVAL: [n x operands]
|
||||||
|
if (Record.size() & 1) return Error("Invalid CE_EXTRACTVAL record");
|
||||||
|
SmallVector<Constant*, 16> Elts;
|
||||||
|
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||||
|
const Type *ElTy = getTypeByID(Record[i]);
|
||||||
|
if (!ElTy) return Error("Invalid CE_EXTRACTVAL record");
|
||||||
|
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
|
||||||
|
}
|
||||||
|
V = ConstantExpr::getExtractValue(Elts[0], &Elts[1], Elts.size()-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case bitc::CST_CODE_CE_INSERTVAL: { // CE_INSERTVAL: [n x operands]
|
||||||
|
if (Record.size() & 1) return Error("Invalid CE_INSERTVAL record");
|
||||||
|
SmallVector<Constant*, 16> Elts;
|
||||||
|
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||||
|
const Type *ElTy = getTypeByID(Record[i]);
|
||||||
|
if (!ElTy) return Error("Invalid CE_INSERTVAL record");
|
||||||
|
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
|
||||||
|
}
|
||||||
|
V = ConstantExpr::getInsertValue(Elts[0], Elts[1],
|
||||||
|
&Elts[2], Elts.size()-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
|
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
|
||||||
if (Record.size() < 3) return Error("Invalid CE_SELECT record");
|
if (Record.size() < 3) return Error("Invalid CE_SELECT record");
|
||||||
V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
|
V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
|
||||||
@ -1301,6 +1324,47 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case bitc::FUNC_CODE_INST_EXTRACTVAL: { // EXTRACTVAL: [n x operands]
|
||||||
|
unsigned OpNum = 0;
|
||||||
|
Value *Agg;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
|
||||||
|
return Error("Invalid EXTRACTVAL record");
|
||||||
|
|
||||||
|
SmallVector<Value*, 16> EXTRACTVALIdx;
|
||||||
|
while (OpNum != Record.size()) {
|
||||||
|
Value *Op;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
||||||
|
return Error("Invalid EXTRACTVAL record");
|
||||||
|
EXTRACTVALIdx.push_back(Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
I = ExtractValueInst::Create(Agg,
|
||||||
|
EXTRACTVALIdx.begin(), EXTRACTVALIdx.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case bitc::FUNC_CODE_INST_INSERTVAL: { // INSERTVAL: [n x operands]
|
||||||
|
unsigned OpNum = 0;
|
||||||
|
Value *Agg;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
|
||||||
|
return Error("Invalid INSERTVAL record");
|
||||||
|
Value *Val;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
|
||||||
|
return Error("Invalid INSERTVAL record");
|
||||||
|
|
||||||
|
SmallVector<Value*, 16> INSERTVALIdx;
|
||||||
|
while (OpNum != Record.size()) {
|
||||||
|
Value *Op;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
||||||
|
return Error("Invalid INSERTVAL record");
|
||||||
|
INSERTVALIdx.push_back(Op);
|
||||||
|
}
|
||||||
|
|
||||||
|
I = InsertValueInst::Create(Agg, Val,
|
||||||
|
INSERTVALIdx.begin(), INSERTVALIdx.end());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
|
case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
Value *TrueVal, *FalseVal, *Cond;
|
Value *TrueVal, *FalseVal, *Cond;
|
||||||
|
@ -610,6 +610,20 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
|||||||
Record.push_back(VE.getValueID(C->getOperand(i)));
|
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Instruction::ExtractValue:
|
||||||
|
Code = bitc::CST_CODE_CE_EXTRACTVAL;
|
||||||
|
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
|
||||||
|
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
|
||||||
|
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Instruction::InsertValue:
|
||||||
|
Code = bitc::CST_CODE_CE_INSERTVAL;
|
||||||
|
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
|
||||||
|
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
|
||||||
|
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Instruction::Select:
|
case Instruction::Select:
|
||||||
Code = bitc::CST_CODE_CE_SELECT;
|
Code = bitc::CST_CODE_CE_SELECT;
|
||||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||||
@ -718,6 +732,16 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
|||||||
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
||||||
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
||||||
break;
|
break;
|
||||||
|
case Instruction::ExtractValue:
|
||||||
|
Code = bitc::FUNC_CODE_INST_EXTRACTVAL;
|
||||||
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
||||||
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
||||||
|
break;
|
||||||
|
case Instruction::InsertValue:
|
||||||
|
Code = bitc::FUNC_CODE_INST_INSERTVAL;
|
||||||
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
||||||
|
PushValueAndType(I.getOperand(i), InstID, Vals, VE);
|
||||||
|
break;
|
||||||
case Instruction::Select:
|
case Instruction::Select:
|
||||||
Code = bitc::FUNC_CODE_INST_SELECT;
|
Code = bitc::FUNC_CODE_INST_SELECT;
|
||||||
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
|
PushValueAndType(I.getOperand(1), InstID, Vals, VE);
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static bool isFirstClassType(const std::pair<const llvm::Type*,
|
static bool isSingleValueType(const std::pair<const llvm::Type*,
|
||||||
unsigned int> &P) {
|
unsigned int> &P) {
|
||||||
return P.first->isFirstClassType();
|
return P.first->isSingleValueType();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) {
|
static bool isIntegerValue(const std::pair<const Value*, unsigned> &V) {
|
||||||
@ -103,10 +103,10 @@ ValueEnumerator::ValueEnumerator(const Module *M) {
|
|||||||
// in the table (have low bit-width).
|
// in the table (have low bit-width).
|
||||||
std::stable_sort(Types.begin(), Types.end(), CompareByFrequency);
|
std::stable_sort(Types.begin(), Types.end(), CompareByFrequency);
|
||||||
|
|
||||||
// Partition the Type ID's so that the first-class types occur before the
|
// Partition the Type ID's so that the single-value types occur before the
|
||||||
// aggregate types. This allows the aggregate types to be dropped from the
|
// aggregate types. This allows the aggregate types to be dropped from the
|
||||||
// type table after parsing the global variable initializers.
|
// type table after parsing the global variable initializers.
|
||||||
std::partition(Types.begin(), Types.end(), isFirstClassType);
|
std::partition(Types.begin(), Types.end(), isSingleValueType);
|
||||||
|
|
||||||
// Now that we rearranged the type table, rebuild TypeMap.
|
// Now that we rearranged the type table, rebuild TypeMap.
|
||||||
for (unsigned i = 0, e = Types.size(); i != e; ++i)
|
for (unsigned i = 0, e = Types.size(); i != e; ++i)
|
||||||
@ -264,11 +264,11 @@ void ValueEnumerator::EnumerateParamAttrs(const PAListPtr &PAL) {
|
|||||||
/// there are none, return -1.
|
/// there are none, return -1.
|
||||||
int ValueEnumerator::PurgeAggregateValues() {
|
int ValueEnumerator::PurgeAggregateValues() {
|
||||||
// If there are no aggregate values at the end of the list, return -1.
|
// If there are no aggregate values at the end of the list, return -1.
|
||||||
if (Values.empty() || Values.back().first->getType()->isFirstClassType())
|
if (Values.empty() || Values.back().first->getType()->isSingleValueType())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Otherwise, remove aggregate values...
|
// Otherwise, remove aggregate values...
|
||||||
while (!Values.empty() && !Values.back().first->getType()->isFirstClassType())
|
while (!Values.empty() && !Values.back().first->getType()->isSingleValueType())
|
||||||
Values.pop_back();
|
Values.pop_back();
|
||||||
|
|
||||||
// ... and return the new size.
|
// ... and return the new size.
|
||||||
|
13
test/Assembler/insertextractvalue.ll
Normal file
13
test/Assembler/insertextractvalue.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; RUN: llvm-as < %s
|
||||||
|
|
||||||
|
;define float @foo({{i32},{float, double}}* %p) {
|
||||||
|
;%t = load {{i32},{float, double}}* %p
|
||||||
|
;%s = extractvalue {{i32},{float, double}} %t, i32 1, i32 0
|
||||||
|
;%r = insertvalue {{i32},{float, double}} %t, double 2.0, i32 1, i32 1
|
||||||
|
;store {{i32},{float, double}} %r, {{i32},{float, double}}* %p
|
||||||
|
;ret float %s
|
||||||
|
;}
|
||||||
|
define float @bar({{i32},{float, double}}* %p) {
|
||||||
|
store {{i32},{float, double}} insertvalue ({{i32},{float, double}}{{i32}{i32 4},{float, double}{float 4.0, double 5.0}}, double 20.0, i32 1, i32 1), {{i32},{float, double}}* %p
|
||||||
|
ret float extractvalue ({{i32},{float, double}}{{i32}{i32 3},{float, double}{float 7.0, double 9.0}}, i32 1, i32 0)
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
; RUN: not llvm-as < %s |& grep {Instruction operands must be first-class}
|
; RUN: llvm-as < %s |& not grep {Instruction operands must be first-class}
|
||||||
; PR826
|
|
||||||
|
; This previously was for PR826, but structs are now first-class so
|
||||||
|
; the following is now valid.
|
||||||
|
|
||||||
%struct_4 = type { i32 }
|
%struct_4 = type { i32 }
|
||||||
|
|
||||||
|
@ -222,7 +222,9 @@ ConstExpr::= CastOps "(" ^ ConstVal to Types ^ ")"
|
|||||||
| vfcmp FPredicates "(" ^ ConstVal ^ "," ConstVal ^ ")"
|
| vfcmp FPredicates "(" ^ ConstVal ^ "," ConstVal ^ ")"
|
||||||
| extractelement "(" ^ ConstVal ^ "," ConstVal ^ ")"
|
| extractelement "(" ^ ConstVal ^ "," ConstVal ^ ")"
|
||||||
| insertelement "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
|
| insertelement "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
|
||||||
| shufflevector "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")" ;
|
| shufflevector "(" ^ ConstVal ^ "," ConstVal ^ "," ConstVal ^ ")"
|
||||||
|
| extractvalue "(" ^ ConstVal IndexList ^ ")"
|
||||||
|
| insertvalue "(" ^ ConstVal ^ "," ConstVal IndexList ^ ")" ;
|
||||||
|
|
||||||
ConstVector ::= ConstVector ^ "," ConstVal | ConstVal ;
|
ConstVector ::= ConstVector ^ "," ConstVal | ConstVal ;
|
||||||
|
|
||||||
@ -373,4 +375,6 @@ MemoryInst ::= malloc Types OptCAlign
|
|||||||
| OptVolatile load Types ValueRef OptCAlign
|
| OptVolatile load Types ValueRef OptCAlign
|
||||||
| OptVolatile store ResolvedVal ^ "," Types ValueRef OptCAlign
|
| OptVolatile store ResolvedVal ^ "," Types ValueRef OptCAlign
|
||||||
| getresult Types ValueRef ^ "," EUINT64VAL
|
| getresult Types ValueRef ^ "," EUINT64VAL
|
||||||
| getelementptr Types ValueRef IndexList ;
|
| getelementptr Types ValueRef IndexList
|
||||||
|
| extractvalue Types ValueRef IndexList
|
||||||
|
| insertvalue Types ValueRef ^ "," Types ValueRef IndexList ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user