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

Unified Diff: src/PNaClTranslator.cpp

Issue 1834473002: Allow Subzero to parse function blocks in parallel. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Clean up code. Created 4 years, 9 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
Index: src/PNaClTranslator.cpp
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index caa0c57c6a05052f1d2926d63039102baba66301..edd0c1ac9e01480f45e5abd5ef373614d6365da5 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -579,11 +579,11 @@ private:
bool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
const std::string &Message) {
- ErrorStatus.assign(Ice::EC_Bitcode);
- ++NumErrors;
- Ice::GlobalContext *Context = Translator.getContext();
- { // Lock while printing out error message.
+ { // Lock while printing out error message and updating state.
+ Ice::GlobalContext *Context = Translator.getContext();
Ice::OstreamLocker L(Context);
+ ErrorStatus.assign(Ice::EC_Bitcode);
John 2016/03/24 17:32:35 Are you using the OstreamLocker to prevent concurr
Karl 2016/03/24 22:35:25 Yes I was using the OstreamLocker. I did it becaus
+ ++NumErrors;
raw_ostream &OldErrStream = setErrStream(Context->getStrError());
NaClBitcodeParser::ErrorAt(Level, Bit, Message);
setErrStream(OldErrStream);
@@ -664,6 +664,11 @@ public:
Context->setBlockParser(this);
}
+ BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
+ NaClBitstreamCursor &Cursor)
+ : NaClBitcodeParser(BlockID, EnclosingParser, Cursor),
+ Context(EnclosingParser->Context) {}
+
~BlockParserBaseClass() override { Context->setBlockParser(nullptr); }
// Returns the printable name of the type of block being parsed.
@@ -679,6 +684,8 @@ public:
protected:
// The context parser that contains the decoded state.
TopLevelParser *Context;
+ // True if ErrorAt has been called in this block.
+ bool BlockHasError = false;
// Constructor for nested block parsers.
BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
@@ -756,6 +763,7 @@ bool TopLevelParser::blockError(const std::string &Message) {
// Generates an error Message with the bit address prefixed to it.
bool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit,
const std::string &Message) {
+ BlockHasError = true;
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
// Note: If dump routines have been turned off, the error messages will not
@@ -1342,22 +1350,30 @@ class FunctionParser : public BlockParserBaseClass {
FunctionParser &operator=(const FunctionParser &) = delete;
public:
- FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
+ FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
+ NaClBcIndexSize_t FcnId)
: BlockParserBaseClass(BlockID, EnclosingParser),
Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
- Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()),
- FuncDecl(Context->getFunctionByID(FcnId)),
+ Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
+ CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
+ NextLocalInstIndex(Context->getNumGlobalIDs()) {}
+
+ FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser,
+ NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor)
+ : BlockParserBaseClass(BlockID, EnclosingParser, Cursor),
+ Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
+ Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)),
CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
NextLocalInstIndex(Context->getNumGlobalIDs()) {}
- bool convertFunction() {
+ std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) {
bool ParserResult;
+ Ice::GlobalContext *Ctx = getTranslator().getContext();
{
- Ice::TimerMarker T(getTranslator().getContext(), FuncDecl->getName());
+ Ice::TimerMarker T(Ctx, FuncDecl->getName());
// Note: The Cfg is created, even when IR generation is disabled. This is
// done to install a CfgLocalAllocator for various internal containers.
- Func = Ice::Cfg::create(getTranslator().getContext(),
- getTranslator().getNextSequenceNumber());
+ Func = Ice::Cfg::create(Ctx, SeqNumber);
Ice::CfgLocalAllocatorScope _(Func.get());
@@ -1374,20 +1390,12 @@ public:
}
ParserResult = ParseThisBlock();
-
- // Note: Once any errors have been found, we turn off all translation of
- // all remaining functions. This allows successive parsing errors to be
- // reported, without adding extra checks to the translator for such
- // parsing errors.
- }
- if (Context->getNumErrors() == 0 && Func) {
- getTranslator().translateFcn(std::move(Func));
- // The translator now has ownership of Func.
- } else {
- Func.reset();
}
- return ParserResult;
+ if (ParserResult || BlockHasError)
+ Func->setError("Unable to parse function");
+
+ return std::move(Func);
John 2016/03/24 17:32:35 no need to move it here -- Func is an xvalue here
Karl 2016/03/24 22:35:26 The compiler disagrees with you!
John 2016/03/25 04:55:22 Ah, Func is a class member... That's one of the wo
Karl 2016/03/29 17:35:02 It uses many instance fields and methods of the Fu
}
~FunctionParser() final = default;
@@ -1434,8 +1442,6 @@ private:
NaClBcIndexSize_t DeclaredNumberBbs = 0;
// The basic block being built.
Ice::CfgNode *CurrentNode = nullptr;
- // The ID for the function.
- NaClBcIndexSize_t FcnId;
// The corresponding function declaration.
Ice::FunctionDeclaration *FuncDecl;
// Holds the dividing point between local and global absolute value indices.
@@ -2984,10 +2990,9 @@ public:
: BlockParserBaseClass(BlockID, Context),
Timer(Ice::TimerStack::TT_parseModule,
Context->getTranslator().getContext()) {}
-
- ~ModuleParser() override = default;
-
+ ~ModuleParser() final = default;
John 2016/03/24 17:32:35 marking the destructor "final" is a pretty strong
Karl 2016/03/24 22:35:25 Moved final keywords (where appropriate) to the cl
const char *getBlockName() const override { return "module"; }
+ NaClBitstreamReader &getReader() { return Record.GetReader(); }
private:
Ice::TimerMarker Timer;
@@ -3015,7 +3020,10 @@ private:
}
bool ParseBlock(unsigned BlockID) override;
- void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); }
+ void ExitBlock() override {
+ installGlobalNamesAndGlobalVarInitializers();
+ Context->getTranslator().getContext()->waitForWorkerThreads();
+ }
void ProcessRecord() override;
};
@@ -3060,6 +3068,33 @@ void ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index,
reportUnableToAssign("Basic block", Index, Name);
}
+class CfgParserWorkItem : public Ice::OptWorkItem {
+ CfgParserWorkItem() = delete;
+ CfgParserWorkItem(const CfgParserWorkItem &) = delete;
+ CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete;
+
+public:
+ CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId,
+ ModuleParser *ModParser, uint64_t StartBit,
+ uint32_t SeqNumber)
+ : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser),
+ StartBit(StartBit), SeqNumber(SeqNumber) {}
+ std::unique_ptr<Ice::Cfg> getParsedCfg() final {
+ NaClBitstreamCursor Cursor(ModParser->getReader());
+ Cursor.JumpToBit(StartBit);
+ FunctionParser Parser(BlockID, ModParser, FcnId, Cursor);
+ return Parser.parseFunction(SeqNumber);
+ }
+ ~CfgParserWorkItem() final {}
John 2016/03/24 17:32:35 make the class final instead?
Karl 2016/03/24 22:35:25 Done.
+
+private:
+ unsigned BlockID;
John 2016/03/24 17:32:35 can these be const?
Karl 2016/03/24 22:35:26 Done, except that ModParser can't be constant (Con
+ NaClBcIndexSize_t FcnId;
+ ModuleParser *ModParser;
+ uint64_t StartBit;
+ uint32_t SeqNumber;
+};
+
bool ModuleParser::ParseBlock(unsigned BlockID) {
switch (BlockID) {
case naclbitc::BLOCKINFO_BLOCK_ID:
@@ -3088,8 +3123,24 @@ bool ModuleParser::ParseBlock(unsigned BlockID) {
}
case naclbitc::FUNCTION_BLOCK_ID: {
installGlobalNamesAndGlobalVarInitializers();
- FunctionParser Parser(BlockID, this);
- return Parser.convertFunction();
+ Ice::GlobalContext *Ctx = Context->getTranslator().getContext();
+ uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber();
+ NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID();
+ if (Ctx->getFlags().getParseParallel()) {
+ uint64_t StartBit = Record.GetCursor().GetCurrentBitNo();
+ if (SkipBlock())
+ return true;
+ Ice::GlobalContext *Ctx = Context->getTranslator().getContext();
+ Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>(
+ BlockID, FcnId, this, StartBit, SeqNumber));
+ return false;
+ } else {
+ FunctionParser Parser(BlockID, this, FcnId);
+ std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber);
+ bool Failed = Func->hasError();
+ getTranslator().translateFcn(std::move(Func));
+ return Failed && !getTranslator().getFlags().getAllowErrorRecovery();
+ }
}
default:
return BlockParserBaseClass::ParseBlock(BlockID);

Powered by Google App Engine
This is Rietveld 408576698