Chromium Code Reviews| Index: src/PNaClTranslator.cpp |
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
| index 11e0b8e3997e1fd7bc28fca0c3126fd9ffcd745f..749e9e0f4013861264bd4131385c88b2d0c8db8d 100644 |
| --- a/src/PNaClTranslator.cpp |
| +++ b/src/PNaClTranslator.cpp |
| @@ -1215,7 +1215,8 @@ public: |
| Func->setFunctionName(FuncDecl->getName()); |
| Func->setReturnType(Signature.getReturnType()); |
| Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); |
| - CurrentNode = installNextBasicBlock(); |
| + constexpr NaClBcIndexSize_t EntryBlock = 0; |
| + CurrentNode = getBasicBlock(EntryBlock); |
| Func->setEntryNode(CurrentNode); |
| for (Ice::Type ArgType : Signature.getArgList()) { |
| Func->addArg(getNextInstVar(ArgType)); |
| @@ -1283,14 +1284,32 @@ public: |
| return Op; |
| } |
| + // Returns the Index-th basic block in the list of basic blocks. |
| + Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { |
| + assert(!isIRGenerationDisabled()); |
| + CfgNodeMap::iterator pos = BbMap.find(Index); |
|
Jim Stichnoth
2015/08/06 17:24:33
Pos
Karl
2015/08/06 18:55:52
Removed. Replaced with simpler code.
|
| + if (pos != BbMap.end()) |
| + return pos->second; |
| + Ice::CfgNode *Bb = Func->makeNode(); |
| + BbMap.insert(std::make_pair(Index, Bb)); |
|
Jim Stichnoth
2015/08/06 17:24:33
I kinda prefer the clarity of this:
BbMap[Index]
Karl
2015/08/06 18:55:52
Did slight modification to your suggestion.
|
| + return Bb; |
| + } |
| + |
| private: |
| + typedef std::map<NaClBcIndexSize_t, Ice::CfgNode*> CfgNodeMap; |
|
Jim Stichnoth
2015/08/06 17:24:33
unordered_map
Karl
2015/08/06 18:55:52
Done.
|
| + |
| Ice::TimerMarker Timer; |
| // The corresponding ICE function defined by the function block. |
| std::unique_ptr<Ice::Cfg> Func; |
| + // The specified number of basic blocks in the bitcode file. |
| + NaClBcIndexSize_t SpecifiedNumBbs = 0; |
| // The index to the current basic block being built. |
| NaClBcIndexSize_t CurrentBbIndex = 0; |
| // The basic block being built. |
| Ice::CfgNode *CurrentNode = nullptr; |
| + // Map from basic block id (as defined in the bitcode file) to |
| + // the corresponding basic block that implements it. |
| + CfgNodeMap BbMap; |
|
John
2015/08/06 17:22:54
The only operations you perform in BbMap are inser
Karl
2015/08/06 18:55:52
Changed to unordered map.
|
| // The ID for the function. |
| NaClBcIndexSize_t FcnId; |
| // The corresponding function declaration. |
| @@ -1333,27 +1352,7 @@ private: |
| void ExitBlock() override; |
| - // Creates and appends a new basic block to the list of basic blocks. |
| - Ice::CfgNode *installNextBasicBlock() { |
| - assert(!isIRGenerationDisabled()); |
| - return Func->makeNode(); |
| - } |
| - |
| - // Returns the Index-th basic block in the list of basic blocks. |
| - Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { |
| - assert(!isIRGenerationDisabled()); |
| - const Ice::NodeList &Nodes = Func->getNodes(); |
| - if (Index >= Nodes.size()) { |
| - std::string Buffer; |
| - raw_string_ostream StrBuf(Buffer); |
| - StrBuf << "Reference to basic block " << Index |
| - << " not found. Must be less than " << Nodes.size(); |
| - Error(StrBuf.str()); |
| - // TODO(kschimpf) Remove error recovery once implementation complete. |
| - Index = 0; |
| - } |
| - return Nodes[Index]; |
| - } |
| + bool verifyAndRenameBasicBlocks(); |
| // Returns the Index-th basic block in the list of basic blocks. |
| // Assumes Index corresponds to a branch instruction. Hence, if |
| @@ -1961,6 +1960,44 @@ private: |
| } |
| }; |
| +bool FunctionParser::verifyAndRenameBasicBlocks() { |
| + const size_t NumFoundBbs = BbMap.size(); |
| + // Verify number of basic blocks found match amount specified in function. |
| + if (NumFoundBbs != SpecifiedNumBbs) { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Function specified " << SpecifiedNumBbs |
|
Jim Stichnoth
2015/08/06 17:24:33
Add "blocks" or "basic blocks" to the message
Karl
2015/08/06 18:55:52
Done.
|
| + << ". Found: " << NumFoundBbs; |
| + Error(StrBuf.str()); |
| + return false; |
| + } |
| + // Verify size limit allowed for basic blocks. |
| + if (NumFoundBbs > NaClBcIndexSize_t_Max) { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Functions can't define more than " << NaClBcIndexSize_t_Max |
| + << "basic blocks. Found: " << NumFoundBbs; |
| + Error(StrBuf.str()); |
| + return false; |
| + } |
| + // Sort list of Bbs, verifying that no basic blocks are missing. |
| + Ice::NodeList SortedBbs; |
| + for (size_t i = 0; i < NumFoundBbs; ++i) { |
| + CfgNodeMap::iterator pos = BbMap.find(i); |
| + if (pos == BbMap.end()) { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Can't find definition for basic block " << i << "."; |
| + Error(StrBuf.str()); |
| + return false; |
| + } |
| + SortedBbs.push_back(pos->second); |
| + } |
| + // Install sorted basic blocks. |
| + Func->replaceNodes(SortedBbs); |
| + return true; |
| +} |
| + |
| void FunctionParser::ExitBlock() { |
| // Check if the last instruction in the function was terminating. |
| if (!InstIsTerminating) { |
| @@ -1972,6 +2009,8 @@ void FunctionParser::ExitBlock() { |
| } |
| if (isIRGenerationDisabled()) |
| return; |
| + if (!verifyAndRenameBasicBlocks()) |
| + return; |
| // Before translating, check for blocks without instructions, and |
| // insert unreachable. This shouldn't happen, but be safe. |
| size_t Index = 0; |
| @@ -2030,14 +2069,11 @@ void FunctionParser::ProcessRecord() { |
| } |
| if (isIRGenerationDisabled()) |
| return; |
| - if (Func->getNodes().size() != 1) { |
| + if (SpecifiedNumBbs != 0) { |
| Error("Duplicate function block count record"); |
| return; |
| } |
| - // Install the basic blocks, skipping bb0 which was created in the |
| - // constructor. |
| - for (size_t i = 1, NumBbs = NumBbsRaw; i < NumBbs; ++i) |
| - installNextBasicBlock(); |
| + SpecifiedNumBbs = NumBbsRaw; |
| return; |
| } |
| case naclbitc::FUNC_CODE_INST_BINOP: { |
| @@ -2863,13 +2899,11 @@ void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, |
| StringType &Name) { |
| if (isIRGenerationDisabled()) |
| return; |
| - if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { |
| - reportUnableToAssign("block", Index, Name); |
| - return; |
| + Ice::CfgNode *Bb = getFunctionParser()->getBasicBlock(Index); |
| + if (Ice::BuildDefs::dump()) { |
|
Jim Stichnoth
2015/08/06 17:24:33
Can you put the BuildDefs::dump() check at the ver
Karl
2015/08/06 18:55:52
Done.
|
| + std::string Nm(Name.data(), Name.size()); |
| + Bb->setName(Nm); |
| } |
| - std::string Nm(Name.data(), Name.size()); |
| - if (Ice::BuildDefs::dump()) |
| - getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); |
| } |
| bool FunctionParser::ParseBlock(unsigned BlockID) { |