Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Unified Diff: src/PNaClTranslator.cpp

Issue 1297433002: Change tracking of basic blocks (within function) to use a vector. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests_lit/parse_errs/Inputs/bad-bb-size.tbc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/PNaClTranslator.cpp
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index f91437c6fa6cbc9d3ef43ca8a163561d479c5d7a..b9dac5552bbd39bfa2a693d7d8b4361c50f41797 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1251,8 +1251,7 @@ public:
Func->setFunctionName(FuncDecl->getName());
Func->setReturnType(Signature.getReturnType());
Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage);
- constexpr NaClBcIndexSize_t EntryBlock = 0;
- CurrentNode = getBasicBlock(EntryBlock);
+ CurrentNode = installNextBasicBlock();
Func->setEntryNode(CurrentNode);
for (Ice::Type ArgType : Signature.getArgList()) {
Func->addArg(getNextInstVar(ArgType));
@@ -1314,31 +1313,20 @@ public:
return Op;
}
- // Returns the Index-th basic block in the list of basic blocks.
- Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
- assert(!isIRGenerationDisabled());
- Ice::CfgNode *&Node = BbMap[Index];
- if (Node == nullptr)
- Node = Func->makeNode();
- return Node;
- }
-
private:
typedef std::unordered_map<NaClBcIndexSize_t, Ice::Operand *> OperandMap;
- typedef std::unordered_map<NaClBcIndexSize_t, Ice::CfgNode *> CfgNodeMap;
Ice::TimerMarker Timer;
+ // The number of words in the bitstream defining the function block.
+ uint64_t NumBytesDefiningFunction = 0;
// 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 number of basic blocks declared for the function block.
+ NaClBcIndexSize_t DeclaredNumberBbs = 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;
// The ID for the function.
NaClBcIndexSize_t FcnId;
// The corresponding function declaration.
@@ -1379,12 +1367,36 @@ private:
void ProcessRecord() override;
- void ExitBlock() override;
+ void EnterBlock(unsigned NumWords) final {
+ // Note: Bitstream defines words as 32-bit values.
+ NumBytesDefiningFunction = NumWords * sizeof(uint32_t);
+ }
- bool verifyAndRenameBasicBlocks();
+ void ExitBlock() override;
bool verifyAllForwardRefsDefined();
+ // Creates and appends a new basic block to the list of basic blocks.
+ Ice::CfgNode *installNextBasicBlock() {
+ assert(!isIRGenerationDisabled());
+ Ice::CfgNode *Node = Func->makeNode();
+ return Node;
+ }
+
+ // Returns the Index-th basic block in the list of basic blocks.
+ Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) {
+ assert(!isIRGenerationDisabled());
+ if (Index >= Func->getNumNodes()) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Reference to basic block " << Index
+ << " not found. Must be less than " << Func->getNumNodes();
+ Error(StrBuf.str());
+ Index = 0;
+ }
+ return Func->getNodes()[Index];
+ }
+
// 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
@@ -1996,44 +2008,6 @@ bool FunctionParser::verifyAllForwardRefsDefined() {
return false;
}
-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
- << "basic blocks. 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->swapNodes(SortedBbs);
- return true;
-}
-
void FunctionParser::ExitBlock() {
// Check if the last instruction in the function was terminating.
if (!InstIsTerminating) {
@@ -2043,12 +2017,18 @@ void FunctionParser::ExitBlock() {
// Recover by inserting an unreachable instruction.
CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get()));
}
+ ++CurrentBbIndex;
+ if (CurrentBbIndex != DeclaredNumberBbs) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Function declared " << DeclaredNumberBbs
+ << " basic blocks, but defined " << CurrentBbIndex << ".";
+ Error(StrBuf.str());
+ }
if (isIRGenerationDisabled())
return;
if (!verifyAllForwardRefsDefined())
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;
@@ -2082,8 +2062,9 @@ void FunctionParser::ProcessRecord() {
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
if (InstIsTerminating) {
InstIsTerminating = false;
+ ++CurrentBbIndex;
if (!isIRGenerationDisabled())
- CurrentNode = getBasicBlock(++CurrentBbIndex);
+ CurrentNode = getBasicBlock(CurrentBbIndex);
}
// The base index for relative indexing.
NaClBcIndexSize_t BaseIndex = getNextInstIndex();
@@ -2092,24 +2073,40 @@ void FunctionParser::ProcessRecord() {
// DECLAREBLOCKS: [n]
if (!isValidRecordSize(1, "count"))
return;
- uint64_t NumBbsRaw = Values[0];
- if (NumBbsRaw == 0) {
- Error("Functions must contain at least one basic block.");
- NumBbsRaw = 1;
- } else if (NumBbsRaw > NaClBcIndexSize_t_Max) {
+ if (DeclaredNumberBbs > 0) {
+ Error("Duplicate function block count record");
+ return;
+ }
+
+ uint64_t NumBbs = Values[0];
+
+ // Check for bad large sizes, since they can make ridiculous memory
+ // requests and hang the user for large amounts of time. Note: We know
+ // that each basic block must have a terminator instruction, and each
+ // instruction is minimally defined by a two-bit abreviation.
+ uint64_t MaxBbs = NumBytesDefiningFunction * (CHAR_BIT >> 1);
+ if (NumBbs > MaxBbs) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
- StrBuf << "To many basic blocks specified: " << NumBbsRaw;
+ StrBuf << "Function defines " << NumBbs
+ << " basic blocks, which is too big for a function containing "
+ << NumBytesDefiningFunction << " bytes";
Error(StrBuf.str());
- NumBbsRaw = NaClBcIndexSize_t_Max;
+ NumBbs = MaxBbs;
}
+
+ if (NumBbs == 0) {
+ Error("Functions must contain at least one basic block.");
+ NumBbs = 1;
+ }
+
+ DeclaredNumberBbs = NumBbs;
if (isIRGenerationDisabled())
return;
- if (SpecifiedNumBbs != 0) {
- Error("Duplicate function block count record");
- return;
- }
- SpecifiedNumBbs = NumBbsRaw;
+ // Install the basic blocks, skipping bb0 which was created in the
+ // constructor.
+ for (size_t i = 1; i < NumBbs; ++i)
+ installNextBasicBlock();
return;
}
case naclbitc::FUNC_CODE_INST_BINOP: {
@@ -2933,9 +2930,13 @@ void FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
return;
if (isIRGenerationDisabled())
return;
- Ice::CfgNode *Bb = getFunctionParser()->getBasicBlock(Index);
+ if (Index >= getFunctionParser()->getFunc()->getNumNodes()) {
+ reportUnableToAssign("block", Index, Name);
+ return;
+ }
std::string Nm(Name.data(), Name.size());
- Bb->setName(Nm);
+ if (Ice::BuildDefs::dump())
+ getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
}
bool FunctionParser::ParseBlock(unsigned BlockID) {
« no previous file with comments | « no previous file | tests_lit/parse_errs/Inputs/bad-bb-size.tbc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698