| Index: src/PNaClTranslator.cpp
|
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
|
| index 5d889ff9a83b612a5c939b42f69511fce9139a0d..bb04d61ff04df4327c9b88f777ae779db0b14d7c 100644
|
| --- a/src/PNaClTranslator.cpp
|
| +++ b/src/PNaClTranslator.cpp
|
| @@ -823,7 +823,7 @@ public:
|
| for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(),
|
| ArgE = LLVMFunc->arg_end();
|
| ArgI != ArgE; ++ArgI) {
|
| - Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType())));
|
| + Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
|
| }
|
| }
|
|
|
| @@ -884,7 +884,7 @@ private:
|
| Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
|
|
|
| // Returns the Index-th basic block in the list of basic blocks.
|
| - Ice::CfgNode *GetBasicBlock(uint32_t Index) {
|
| + Ice::CfgNode *getBasicBlock(uint32_t Index) {
|
| const Ice::NodeList &Nodes = Func->getNodes();
|
| if (Index >= Nodes.size()) {
|
| std::string Buffer;
|
| @@ -907,33 +907,34 @@ private:
|
| Error("Branch to entry block not allowed");
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| }
|
| - return GetBasicBlock(Index);
|
| + return getBasicBlock(Index);
|
| }
|
|
|
| - // Generates the next available local variable using the given
|
| - // type. Note: if Ty is void, this function returns NULL.
|
| - Ice::Variable *NextInstVar(Ice::Type Ty) {
|
| - if (Ty == Ice::IceType_void)
|
| - return NULL;
|
| + // Generates the next available local variable using the given type.
|
| + Ice::Variable *getNextInstVar(Ice::Type Ty) {
|
| + if (Ty == Ice::IceType_void) {
|
| + Error("Can't define instruction value using type void");
|
| + // Recover since we can't throw an exception.
|
| + Ty = Ice::IceType_i32;
|
| + }
|
| Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
|
| LocalOperands.push_back(Var);
|
| return Var;
|
| }
|
|
|
| - // Converts a relative index (to the next instruction to be read) to
|
| - // an absolute value index.
|
| - uint32_t convertRelativeToAbsIndex(int32_t Id) {
|
| - int32_t AbsNextId = CachedNumGlobalValueIDs + LocalOperands.size();
|
| - if (Id > 0 && AbsNextId < Id) {
|
| + // Converts a relative index (wrt to BaseIndex) to an absolute value
|
| + // index.
|
| + uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) {
|
| + if (BaseIndex < Id) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| StrBuf << "Invalid relative value id: " << Id
|
| - << " (must be <= " << AbsNextId << ")";
|
| + << " (must be <= " << BaseIndex << ")";
|
| Error(StrBuf.str());
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| return 0;
|
| }
|
| - return AbsNextId - Id;
|
| + return BaseIndex - Id;
|
| }
|
|
|
| // Returns the value referenced by the given value Index.
|
| @@ -954,10 +955,15 @@ private:
|
| return LocalOperands[LocalIndex];
|
| }
|
|
|
| - // Returns the relative operand (wrt to next instruction) referenced by
|
| - // the given value index.
|
| - Ice::Operand *getRelativeOperand(uint32_t Index) {
|
| - return getOperand(convertRelativeToAbsIndex(Index));
|
| + // Returns the relative operand (wrt to BaseIndex) referenced by
|
| + // the given value Index.
|
| + Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) {
|
| + return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
|
| + }
|
| +
|
| + // Returns the absolute index of the next value generating instruction.
|
| + uint32_t getNextInstIndex() const {
|
| + return CachedNumGlobalValueIDs + LocalOperands.size();
|
| }
|
|
|
| // Generates type error message for binary operator Op
|
| @@ -1316,9 +1322,10 @@ void FunctionParser::ProcessRecord() {
|
| const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
|
| if (InstIsTerminating) {
|
| InstIsTerminating = false;
|
| - CurrentNode = GetBasicBlock(++CurrentBbIndex);
|
| + CurrentNode = getBasicBlock(++CurrentBbIndex);
|
| }
|
| - Ice::Inst *Inst = NULL;
|
| + // The base index for relative indexing.
|
| + int32_t BaseIndex = getNextInstIndex();
|
| switch (Record.GetCode()) {
|
| case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
|
| // DECLAREBLOCKS: [n]
|
| @@ -1344,8 +1351,8 @@ void FunctionParser::ProcessRecord() {
|
| // BINOP: [opval, opval, opcode]
|
| if (!isValidRecordSize(3, "function block binop"))
|
| return;
|
| - Ice::Operand *Op1 = getRelativeOperand(Values[0]);
|
| - Ice::Operand *Op2 = getRelativeOperand(Values[1]);
|
| + Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
|
| + Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
|
| Ice::Type Type1 = Op1->getType();
|
| Ice::Type Type2 = Op2->getType();
|
| if (Type1 != Type2) {
|
| @@ -1360,15 +1367,15 @@ void FunctionParser::ProcessRecord() {
|
| Ice::InstArithmetic::OpKind Opcode;
|
| if (!convertBinopOpcode(Values[2], Type1, Opcode))
|
| return;
|
| - Ice::Variable *Dest = NextInstVar(Type1);
|
| - Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2);
|
| + CurrentNode->appendInst(Ice::InstArithmetic::create(
|
| + Func, Opcode, getNextInstVar(Type1), Op1, Op2));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_CAST: {
|
| // CAST: [opval, destty, castopc]
|
| if (!isValidRecordSize(3, "function block cast"))
|
| return;
|
| - Ice::Operand *Src = getRelativeOperand(Values[0]);
|
| + Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
|
| Type *CastType = Context->getTypeByID(Values[1]);
|
| Instruction::CastOps LLVMCastOp;
|
| Ice::InstCast::OpKind CastKind;
|
| @@ -1389,15 +1396,16 @@ void FunctionParser::ProcessRecord() {
|
| Error(StrBuf.str());
|
| return;
|
| }
|
| - Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType));
|
| - Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
|
| + CurrentNode->appendInst(Ice::InstCast::create(
|
| + Func, CastKind, getNextInstVar(Context->convertToIceType(CastType)),
|
| + Src));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_VSELECT: {
|
| // VSELECT: [opval, opval, pred]
|
| - Ice::Operand *ThenVal = getOperand(convertRelativeToAbsIndex(Values[0]));
|
| + Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
|
| Ice::Type ThenType = ThenVal->getType();
|
| - Ice::Operand *ElseVal = getOperand(convertRelativeToAbsIndex(Values[1]));
|
| + Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
|
| Ice::Type ElseType = ElseVal->getType();
|
| if (ThenType != ElseType) {
|
| std::string Buffer;
|
| @@ -1407,7 +1415,7 @@ void FunctionParser::ProcessRecord() {
|
| Error(StrBuf.str());
|
| return;
|
| }
|
| - Ice::Operand *CondVal = getOperand(convertRelativeToAbsIndex(Values[2]));
|
| + Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
|
| Ice::Type CondType = CondVal->getType();
|
| if (isVectorType(CondType)) {
|
| if (!isVectorType(ThenType) ||
|
| @@ -1427,15 +1435,15 @@ void FunctionParser::ProcessRecord() {
|
| Error(StrBuf.str());
|
| return;
|
| }
|
| - Ice::Variable *DestVal = NextInstVar(ThenType);
|
| - Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal);
|
| + CurrentNode->appendInst(Ice::InstSelect::create(
|
| + Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
|
| // EXTRACTELT: [opval, opval]
|
| if (!isValidRecordSize(2, "function block extract element"))
|
| return;
|
| - Ice::Operand *Vec = getRelativeOperand(Values[0]);
|
| + Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
|
| Ice::Type VecType = Vec->getType();
|
| if (!Ice::isVectorType(VecType)) {
|
| std::string Buffer;
|
| @@ -1443,7 +1451,7 @@ void FunctionParser::ProcessRecord() {
|
| StrBuf << "Extractelement not on vector. Found: " << Vec;
|
| Error(StrBuf.str());
|
| }
|
| - Ice::Operand *Index = getRelativeOperand(Values[1]);
|
| + Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
|
| if (Index->getType() != Ice::IceType_i32) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -1452,15 +1460,15 @@ void FunctionParser::ProcessRecord() {
|
| }
|
| // TODO(kschimpf): Restrict index to a legal constant index (once
|
| // constants can be defined).
|
| - Ice::Variable *Dest = NextInstVar(typeElementType(VecType));
|
| - Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index);
|
| + CurrentNode->appendInst(Ice::InstExtractElement::create(
|
| + Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_INSERTELT: {
|
| // INSERTELT: [opval, opval, opval]
|
| if (!isValidRecordSize(3, "function block insert element"))
|
| return;
|
| - Ice::Operand *Vec = getRelativeOperand(Values[0]);
|
| + Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
|
| Ice::Type VecType = Vec->getType();
|
| if (!Ice::isVectorType(VecType)) {
|
| std::string Buffer;
|
| @@ -1468,7 +1476,7 @@ void FunctionParser::ProcessRecord() {
|
| StrBuf << "Insertelement not on vector. Found: " << Vec;
|
| Error(StrBuf.str());
|
| }
|
| - Ice::Operand *Elt = getRelativeOperand(Values[1]);
|
| + Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
|
| Ice::Type EltType = Elt->getType();
|
| if (EltType != typeElementType(VecType)) {
|
| std::string Buffer;
|
| @@ -1477,7 +1485,7 @@ void FunctionParser::ProcessRecord() {
|
| << ". Found: " << Elt;
|
| Error(StrBuf.str());
|
| }
|
| - Ice::Operand *Index = getRelativeOperand(Values[2]);
|
| + Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
|
| if (Index->getType() != Ice::IceType_i32) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -1486,16 +1494,16 @@ void FunctionParser::ProcessRecord() {
|
| }
|
| // TODO(kschimpf): Restrict index to a legal constant index (once
|
| // constants can be defined).
|
| - Ice::Variable *Dest = NextInstVar(EltType);
|
| - Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
|
| + CurrentNode->appendInst(Ice::InstInsertElement::create(
|
| + Func, getNextInstVar(EltType), Vec, Elt, Index));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_CMP2: {
|
| // CMP2: [opval, opval, pred]
|
| if (!isValidRecordSize(3, "function block compare"))
|
| return;
|
| - Ice::Operand *Op1 = getRelativeOperand(Values[0]);
|
| - Ice::Operand *Op2 = getRelativeOperand(Values[1]);
|
| + Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
|
| + Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
|
| Ice::Type Op1Type = Op1->getType();
|
| Ice::Type Op2Type = Op2->getType();
|
| if (Op1Type != Op2Type) {
|
| @@ -1515,7 +1523,7 @@ void FunctionParser::ProcessRecord() {
|
| Error(StrBuf.str());
|
| return;
|
| }
|
| - Ice::Variable *Dest = NextInstVar(DestType);
|
| + Ice::Variable *Dest = getNextInstVar(DestType);
|
| if (isIntegerType(Op1Type)) {
|
| Ice::InstIcmp::ICond Cond;
|
| if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
|
| @@ -1527,7 +1535,8 @@ void FunctionParser::ProcessRecord() {
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| Cond = Ice::InstIcmp::Eq;
|
| }
|
| - Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2);
|
| + CurrentNode->appendInst(
|
| + Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
|
| } else if (isFloatingType(Op1Type)){
|
| Ice::InstFcmp::FCond Cond;
|
| if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
|
| @@ -1539,7 +1548,8 @@ void FunctionParser::ProcessRecord() {
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| Cond = Ice::InstFcmp::False;
|
| }
|
| - Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2);
|
| + CurrentNode->appendInst(
|
| + Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
|
| } else {
|
| // Not sure this can happen, but be safe.
|
| std::string Buffer;
|
| @@ -1555,9 +1565,10 @@ void FunctionParser::ProcessRecord() {
|
| if (!isValidRecordSizeInRange(0, 1, "function block ret"))
|
| return;
|
| if (Values.size() == 0) {
|
| - Inst = Ice::InstRet::create(Func);
|
| + CurrentNode->appendInst(Ice::InstRet::create(Func));
|
| } else {
|
| - Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
|
| + CurrentNode->appendInst(
|
| + Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
|
| }
|
| InstIsTerminating = true;
|
| break;
|
| @@ -1568,12 +1579,12 @@ void FunctionParser::ProcessRecord() {
|
| Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
|
| if (Block == NULL)
|
| return;
|
| - Inst = Ice::InstBr::create(Func, Block);
|
| + CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
|
| } else {
|
| // BR: [bb#, bb#, opval]
|
| if (!isValidRecordSize(3, "function block branch"))
|
| return;
|
| - Ice::Operand *Cond = getRelativeOperand(Values[2]);
|
| + Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
|
| if (Cond->getType() != Ice::IceType_i1) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -1585,16 +1596,51 @@ void FunctionParser::ProcessRecord() {
|
| Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
|
| if (ThenBlock == NULL || ElseBlock == NULL)
|
| return;
|
| - Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock);
|
| + CurrentNode->appendInst(
|
| + Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
|
| }
|
| InstIsTerminating = true;
|
| break;
|
| }
|
| + case naclbitc::FUNC_CODE_INST_PHI: {
|
| + // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
|
| + if (!isValidRecordSizeAtLeast(3, "function block phi"))
|
| + return;
|
| + if ((Values.size() & 0x1) == 0) {
|
| + // Not an odd number of values.
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "function block phi record size not valid: " << Values.size();
|
| + Error(StrBuf.str());
|
| + return;
|
| + }
|
| + Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0]));
|
| + if (Ty == Ice::IceType_void) {
|
| + Error("Phi record using type void not allowed");
|
| + return;
|
| + }
|
| + Ice::Variable *Dest = getNextInstVar(Ty);
|
| + Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest);
|
| + for (unsigned i = 1; i < Values.size(); i += 2) {
|
| + Ice::Operand *Op =
|
| + getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
|
| + if (Op->getType() != Ty) {
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op;
|
| + Error(StrBuf.str());
|
| + return;
|
| + }
|
| + Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
|
| + }
|
| + CurrentNode->appendInst(Phi);
|
| + break;
|
| + }
|
| case naclbitc::FUNC_CODE_INST_ALLOCA: {
|
| // ALLOCA: [Size, align]
|
| if (!isValidRecordSize(2, "function block alloca"))
|
| return;
|
| - Ice::Operand *ByteCount = getRelativeOperand(Values[0]);
|
| + Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
|
| if (ByteCount->getType() != Ice::IceType_i32) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| @@ -1604,15 +1650,16 @@ void FunctionParser::ProcessRecord() {
|
| }
|
| unsigned Alignment;
|
| extractAlignment("Alloca", Values[1], Alignment);
|
| - Ice::Variable *Dest = NextInstVar(Context->getIcePointerType());
|
| - Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest);
|
| + CurrentNode->appendInst(
|
| + Ice::InstAlloca::create(Func, ByteCount, Alignment,
|
| + getNextInstVar(Context->getIcePointerType())));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_LOAD: {
|
| // LOAD: [address, align, ty]
|
| if (!isValidRecordSize(3, "function block load"))
|
| return;
|
| - Ice::Operand *Address = getRelativeOperand(Values[0]);
|
| + Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
|
| if (!isValidPointerType(Address, "Load"))
|
| return;
|
| unsigned Alignment;
|
| @@ -1620,23 +1667,24 @@ void FunctionParser::ProcessRecord() {
|
| Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
|
| if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
|
| return;
|
| - Ice::Variable *Dest = NextInstVar(Ty);
|
| - Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment);
|
| + CurrentNode->appendInst(
|
| + Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
|
| break;
|
| }
|
| case naclbitc::FUNC_CODE_INST_STORE: {
|
| // STORE: [address, value, align]
|
| if (!isValidRecordSize(3, "function block store"))
|
| return;
|
| - Ice::Operand *Address = getRelativeOperand(Values[0]);
|
| + Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
|
| if (!isValidPointerType(Address, "Store"))
|
| return;
|
| - Ice::Operand *Value = getRelativeOperand(Values[1]);
|
| + Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
|
| unsigned Alignment;
|
| extractAlignment("Store", Values[2], Alignment);
|
| if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
|
| return;
|
| - Inst = Ice::InstStore::create(Func, Value, Address, Alignment);
|
| + CurrentNode->appendInst(
|
| + Ice::InstStore::create(Func, Value, Address, Alignment));
|
| break;
|
| }
|
| default:
|
| @@ -1644,8 +1692,6 @@ void FunctionParser::ProcessRecord() {
|
| BlockParserBaseClass::ProcessRecord();
|
| break;
|
| }
|
| - if (Inst)
|
| - CurrentNode->appendInst(Inst);
|
| }
|
|
|
| /// Parses constants within a function block.
|
|
|