Chromium Code Reviews| Index: src/PNaClTranslator.cpp |
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
| index 5d889ff9a83b612a5c939b42f69511fce9139a0d..6eb64583b05965b527d0252b253019396fa366c5 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,16 @@ 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 +1397,17 @@ 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 +1417,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 +1437,16 @@ 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 +1454,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 +1463,16 @@ 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 +1480,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 +1489,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 +1498,17 @@ 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 +1528,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 +1540,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 +1553,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 +1570,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 +1584,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 +1601,53 @@ 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, val0,bb0, ...] |
|
jvoung (off chromium)
2014/09/11 19:14:43
add a space between val0, bb0 ?
Jim Stichnoth
2014/09/11 19:31:29
I assumed that was intentional grouping, e.g.
[t
Karl
2014/09/11 21:43:04
Actually, the space probably be added. Clarifying
|
| + 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; |
| + } |
| + unsigned NumValues = Values.size()/2; |
|
Jim Stichnoth
2014/09/11 18:26:40
Maybe use "Values.size() >> 1" to make it a little
Karl
2014/09/11 21:43:04
Done.
|
| + 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, NumValues, Dest); |
| + for (unsigned i = 1, e = Values.size(); i < e; i += 2) { |
| + Ice::Operand *Op = |
| + getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
| + if (Op->getType() != Ty) { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Phi node expects type " << Ty << " but found: " << Op; |
|
Jim Stichnoth
2014/09/11 18:26:40
Nit: maybe "operand" or "instruction" instead of "
Karl
2014/09/11 21:43:04
Done.
|
| + Error(StrBuf.str()); |
| + return; |
| + } |
| + Phi->addArgument(Op, getBasicBlock(Values[i+1])); |
|
Jim Stichnoth
2014/09/11 18:26:40
hmm, did clang-format really allow "i+1" without s
Karl
2014/09/11 21:43:04
Done.
|
| + } |
| + 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 +1657,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 +1674,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 +1699,6 @@ void FunctionParser::ProcessRecord() { |
| BlockParserBaseClass::ProcessRecord(); |
| break; |
| } |
| - if (Inst) |
| - CurrentNode->appendInst(Inst); |
| } |
| /// Parses constants within a function block. |