| Index: src/PNaClTranslator.cpp
|
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
|
| index 1eb1767dbf195f0c9afb9a9ccdb218d13665b708..fe0285a0b1655816acbb9db240af3aff294c1f39 100644
|
| --- a/src/PNaClTranslator.cpp
|
| +++ b/src/PNaClTranslator.cpp
|
| @@ -1306,12 +1306,6 @@ public:
|
| return Context->getGlobalConstantByID(Index);
|
| }
|
| NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
|
| - if (LocalIndex >= LocalOperands.size()) {
|
| - std::string Buffer;
|
| - raw_string_ostream StrBuf(Buffer);
|
| - StrBuf << "Value index " << Index << " not defined!";
|
| - Fatal(StrBuf.str());
|
| - }
|
| Ice::Operand *Op = LocalOperands[LocalIndex];
|
| if (Op == nullptr) {
|
| if (isIRGenerationDisabled())
|
| @@ -1334,6 +1328,7 @@ public:
|
| }
|
|
|
| private:
|
| + typedef std::unordered_map<NaClBcIndexSize_t, Ice::Operand *> OperandMap;
|
| typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap;
|
|
|
| Ice::TimerMarker Timer;
|
| @@ -1356,7 +1351,7 @@ private:
|
| size_t CachedNumGlobalValueIDs;
|
| // Holds operands local to the function block, based on indices
|
| // defined in the bitcode file.
|
| - std::vector<Ice::Operand *> LocalOperands;
|
| + OperandMap LocalOperands;
|
| // Holds the index within LocalOperands corresponding to the next
|
| // instruction that generates a value.
|
| NaClBcIndexSize_t NextLocalInstIndex;
|
| @@ -1392,6 +1387,8 @@ private:
|
|
|
| bool verifyAndRenameBasicBlocks();
|
|
|
| + bool verifyAllForwardRefsDefined();
|
| +
|
| // Returns the Index-th basic block in the list of basic blocks.
|
| // Assumes Index corresponds to a branch instruction. Hence, if
|
| // the branch references the entry block, it also generates a
|
| @@ -1467,34 +1464,26 @@ private:
|
| assert(Op || isIRGenerationDisabled());
|
| // Check if simple push works.
|
| NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs;
|
| - if (LocalIndex == LocalOperands.size()) {
|
| - LocalOperands.push_back(Op);
|
| - return;
|
| - }
|
| -
|
| - // Must be forward reference, expand vector to accommodate.
|
| - if (LocalIndex >= LocalOperands.size())
|
| - LocalOperands.resize(LocalIndex + 1);
|
|
|
| // If element not defined, set it.
|
| - Ice::Operand *OldOp = LocalOperands[LocalIndex];
|
| - if (OldOp == nullptr) {
|
| - LocalOperands[LocalIndex] = Op;
|
| + Ice::Operand *&IndexedOp = LocalOperands[LocalIndex];
|
| + if (IndexedOp == nullptr) {
|
| + IndexedOp = Op;
|
| return;
|
| }
|
|
|
| - // See if forward reference matches.
|
| - if (OldOp == Op)
|
| + // See if forward reference matchers.
|
| + if (IndexedOp == Op)
|
| return;
|
|
|
| // Error has occurred.
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| StrBuf << "Multiple definitions for index " << Index << ": " << *Op
|
| - << " and " << *OldOp;
|
| + << " and " << *IndexedOp;
|
| Error(StrBuf.str());
|
| // TODO(kschimpf) Remove error recovery once implementation complete.
|
| - LocalOperands[LocalIndex] = Op;
|
| + IndexedOp = Op;
|
| }
|
|
|
| // Returns the relative operand (wrt to BaseIndex) referenced by
|
| @@ -1998,6 +1987,26 @@ private:
|
| }
|
| };
|
|
|
| +bool FunctionParser::verifyAllForwardRefsDefined() {
|
| + NaClBcIndexSize_t NumInstructions =
|
| + NextLocalInstIndex - CachedNumGlobalValueIDs;
|
| + if (NumInstructions == LocalOperands.size())
|
| + return true;
|
| + // Find undefined forward references and report.
|
| + std::vector<NaClBcIndexSize_t> UndefinedFwdRefs;
|
| + for (const OperandMap::value_type &Elmt : LocalOperands)
|
| + if (Elmt.first >= NextLocalInstIndex)
|
| + UndefinedFwdRefs.push_back(Elmt.first);
|
| + std::sort(UndefinedFwdRefs.begin(), UndefinedFwdRefs.end());
|
| + for (const NaClBcIndexSize_t Index : UndefinedFwdRefs) {
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Instruction forward reference not defined: " << Index;
|
| + Error(StrBuf.str());
|
| + }
|
| + return false;
|
| +}
|
| +
|
| bool FunctionParser::verifyAndRenameBasicBlocks() {
|
| const size_t NumFoundBbs = BbMap.size();
|
| // Verify number of basic blocks found match amount specified in function.
|
| @@ -2047,6 +2056,8 @@ void FunctionParser::ExitBlock() {
|
| }
|
| if (isIRGenerationDisabled())
|
| return;
|
| + if (!verifyAllForwardRefsDefined())
|
| + return;
|
| if (!verifyAndRenameBasicBlocks())
|
| return;
|
| // Before translating, check for blocks without instructions, and
|
|
|