Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index 0c0623112e89dcf5839e4220406c07ef98edd2f7..249875fe42a6f6c4b692a2075c990b3cb203cadc 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -1052,19 +1052,27 @@ public: |
FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) |
: BlockParserBaseClass(BlockID, EnclosingParser), |
Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), |
- Func(isIRGenerationDisabled() |
- ? nullptr |
- : Ice::Cfg::create(getTranslator().getContext())), |
- CurrentBbIndex(0), FcnId(Context->getNextFunctionBlockValueID()), |
+ Func(nullptr), CurrentBbIndex(0), |
+ FcnId(Context->getNextFunctionBlockValueID()), |
FuncDecl(Context->getFunctionByID(FcnId)), |
CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), |
NextLocalInstIndex(Context->getNumGlobalIDs()), |
- InstIsTerminating(false) { |
- if (ALLOW_DUMP && getFlags().TimeEachFunction) |
- getTranslator().getContext()->pushTimer( |
- getTranslator().getContext()->getTimerID( |
- Ice::GlobalContext::TSK_Funcs, FuncDecl->getName()), |
- Ice::GlobalContext::TSK_Funcs); |
+ InstIsTerminating(false) {} |
+ |
+ bool convertFunction() { |
+ const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs; |
+ Ice::TimerIdT TimerID = 0; |
+ const bool TimeThisFunction = ALLOW_DUMP && getFlags().TimeEachFunction; |
+ if (TimeThisFunction) { |
+ TimerID = getTranslator().getContext()->getTimerID(StackID, |
+ FuncDecl->getName()); |
+ getTranslator().getContext()->pushTimer(TimerID, StackID); |
+ } |
+ |
+ if (!isIRGenerationDisabled()) |
+ Func = Ice::Cfg::create(getTranslator().getContext()); |
+ Ice::Cfg::setCurrentCfg(Func.get()); |
+ |
// TODO(kschimpf) Clean up API to add a function signature to |
// a CFG. |
const Ice::FuncSigType &Signature = FuncDecl->getSignature(); |
@@ -1084,13 +1092,34 @@ public: |
Func->addArg(getNextInstVar(ArgType)); |
} |
} |
+ bool ParserResult = ParseThisBlock(); |
+ |
+ // Temporarily end per-function timing, which will be resumed by |
+ // the translator function. This is because translation may be |
+ // done asynchronously in a separate thread. |
+ if (TimeThisFunction) |
+ getTranslator().getContext()->popTimer(TimerID, StackID); |
+ |
+ Ice::Cfg::setCurrentCfg(nullptr); |
+ // 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) { |
+ getTranslator().translateFcn(std::move(Func)); |
+ // The translator now has ownership of Func. |
+ } else { |
+ Func.reset(); |
+ } |
+ |
+ return ParserResult; |
} |
~FunctionParser() final {} |
const char *getBlockName() const override { return "function"; } |
- Ice::Cfg *getFunc() const { return Func; } |
+ Ice::Cfg *getFunc() const { return Func.get(); } |
uint32_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } |
@@ -1130,7 +1159,7 @@ public: |
private: |
Ice::TimerMarker Timer; |
// The corresponding ICE function defined by the function block. |
- Ice::Cfg *Func; |
+ std::unique_ptr<Ice::Cfg> Func; |
// The index to the current basic block being built. |
uint32_t CurrentBbIndex; |
// The basic block being built. |
@@ -1153,15 +1182,6 @@ private: |
// Upper limit of alignment power allowed by LLVM |
static const uint32_t AlignPowerLimit = 29; |
- void popTimerIfTimingEachFunction() const { |
- if (ALLOW_DUMP && getFlags().TimeEachFunction) { |
- getTranslator().getContext()->popTimer( |
- getTranslator().getContext()->getTimerID( |
- Ice::GlobalContext::TSK_Funcs, FuncDecl->getName()), |
- Ice::GlobalContext::TSK_Funcs); |
- } |
- } |
- |
// Extracts the corresponding Alignment to use, given the AlignPower |
// (i.e. 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the |
// name of the instruction the alignment appears in. |
@@ -1820,14 +1840,12 @@ private: |
if (Ty == Ice::IceType_void) |
return; |
Ice::Variable *Var = getNextInstVar(Ty); |
- CurrentNode->appendInst(Ice::InstAssign::create(Func, Var, Var)); |
+ CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); |
} |
}; |
void FunctionParser::ExitBlock() { |
if (isIRGenerationDisabled()) { |
- popTimerIfTimingEachFunction(); |
- delete Func; |
return; |
} |
// Before translating, check for blocks without instructions, and |
@@ -1840,21 +1858,11 @@ void FunctionParser::ExitBlock() { |
StrBuf << "Basic block " << Index << " contains no instructions"; |
Error(StrBuf.str()); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
- Node->appendInst(Ice::InstUnreachable::create(Func)); |
+ Node->appendInst(Ice::InstUnreachable::create(Func.get())); |
} |
++Index; |
} |
Func->computePredecessors(); |
- // Temporarily end per-function timing, which will be resumed by the |
- // translator function. This is because translation may be done |
- // asynchronously in a separate thread. |
- popTimerIfTimingEachFunction(); |
- // Note: Once any errors have been found, we turn off all |
- // translation of all remaining functions. This allows use to see |
- // multiple errors, without adding extra checks to the translator |
- // for such parsing errors. |
- if (Context->getNumErrors() == 0) |
- getTranslator().translateFcn(Func); |
} |
void FunctionParser::ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, |
@@ -1930,7 +1938,7 @@ void FunctionParser::ProcessRecord() { |
return; |
} |
CurrentNode->appendInst(Ice::InstArithmetic::create( |
- Func, Opcode, getNextInstVar(Type1), Op1, Op2)); |
+ Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_CAST: { |
@@ -1949,8 +1957,8 @@ void FunctionParser::ProcessRecord() { |
appendErrorInstruction(CastType); |
return; |
} |
- CurrentNode->appendInst( |
- Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); |
+ CurrentNode->appendInst(Ice::InstCast::create( |
+ Func.get(), CastKind, getNextInstVar(CastType), Src)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_VSELECT: { |
@@ -1999,7 +2007,7 @@ void FunctionParser::ProcessRecord() { |
return; |
} |
CurrentNode->appendInst(Ice::InstSelect::create( |
- Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); |
+ Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_EXTRACTELT: { |
@@ -2026,7 +2034,7 @@ void FunctionParser::ProcessRecord() { |
return; |
} |
CurrentNode->appendInst(Ice::InstExtractElement::create( |
- Func, getNextInstVar(typeElementType(VecType)), Vec, Index)); |
+ Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_INSERTELT: { |
@@ -2055,7 +2063,7 @@ void FunctionParser::ProcessRecord() { |
return; |
} |
CurrentNode->appendInst(Ice::InstInsertElement::create( |
- Func, getNextInstVar(VecType), Vec, Elt, Index)); |
+ Func.get(), getNextInstVar(VecType), Vec, Elt, Index)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_CMP2: { |
@@ -2100,7 +2108,7 @@ void FunctionParser::ProcessRecord() { |
appendErrorInstruction(DestType); |
} |
CurrentNode->appendInst( |
- Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2)); |
+ Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2)); |
} else if (isFloatingType(Op1Type)) { |
Ice::InstFcmp::FCond Cond; |
if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { |
@@ -2112,7 +2120,7 @@ void FunctionParser::ProcessRecord() { |
appendErrorInstruction(DestType); |
} |
CurrentNode->appendInst( |
- Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2)); |
+ Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2)); |
} else { |
// Not sure this can happen, but be safe. |
std::string Buffer; |
@@ -2131,14 +2139,14 @@ void FunctionParser::ProcessRecord() { |
if (Values.empty()) { |
if (isIRGenerationDisabled()) |
return; |
- CurrentNode->appendInst(Ice::InstRet::create(Func)); |
+ CurrentNode->appendInst(Ice::InstRet::create(Func.get())); |
} else { |
Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex); |
if (isIRGenerationDisabled()) { |
assert(RetVal == nullptr); |
return; |
} |
- CurrentNode->appendInst(Ice::InstRet::create(Func, RetVal)); |
+ CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal)); |
} |
InstIsTerminating = true; |
return; |
@@ -2151,7 +2159,7 @@ void FunctionParser::ProcessRecord() { |
Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); |
if (Block == nullptr) |
return; |
- CurrentNode->appendInst(Ice::InstBr::create(Func, Block)); |
+ CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block)); |
} else { |
// BR: [bb#, bb#, opval] |
if (!isValidRecordSize(3, "branch")) |
@@ -2174,7 +2182,7 @@ void FunctionParser::ProcessRecord() { |
if (ThenBlock == nullptr || ElseBlock == nullptr) |
return; |
CurrentNode->appendInst( |
- Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock)); |
+ Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock)); |
} |
InstIsTerminating = true; |
return; |
@@ -2221,8 +2229,9 @@ void FunctionParser::ProcessRecord() { |
if (!isValidRecordSize(4 + NumCases * 4, "switch")) |
return; |
Ice::InstSwitch *Switch = |
- isIRGenDisabled ? nullptr : Ice::InstSwitch::create(Func, NumCases, |
- Cond, DefaultLabel); |
+ isIRGenDisabled |
+ ? nullptr |
+ : Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel); |
unsigned ValCaseIndex = 4; // index to beginning of case entry. |
for (unsigned CaseIndex = 0; CaseIndex < NumCases; |
++CaseIndex, ValCaseIndex += 4) { |
@@ -2253,7 +2262,7 @@ void FunctionParser::ProcessRecord() { |
return; |
if (isIRGenerationDisabled()) |
return; |
- CurrentNode->appendInst(Ice::InstUnreachable::create(Func)); |
+ CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); |
InstIsTerminating = true; |
return; |
} |
@@ -2285,7 +2294,8 @@ void FunctionParser::ProcessRecord() { |
return; |
} |
Ice::Variable *Dest = getNextInstVar(Ty); |
- Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest); |
+ Ice::InstPhi *Phi = |
+ Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); |
for (unsigned i = 1; i < Values.size(); i += 2) { |
Ice::Operand *Op = |
getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); |
@@ -2324,8 +2334,8 @@ void FunctionParser::ProcessRecord() { |
appendErrorInstruction(PtrTy); |
return; |
} |
- CurrentNode->appendInst(Ice::InstAlloca::create(Func, ByteCount, Alignment, |
- getNextInstVar(PtrTy))); |
+ CurrentNode->appendInst(Ice::InstAlloca::create( |
+ Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); |
return; |
} |
case naclbitc::FUNC_CODE_INST_LOAD: { |
@@ -2349,8 +2359,8 @@ void FunctionParser::ProcessRecord() { |
appendErrorInstruction(Ty); |
return; |
} |
- CurrentNode->appendInst( |
- Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment)); |
+ CurrentNode->appendInst(Ice::InstLoad::create( |
+ Func.get(), getNextInstVar(Ty), Address, Alignment)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_STORE: { |
@@ -2370,7 +2380,7 @@ void FunctionParser::ProcessRecord() { |
if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) |
return; |
CurrentNode->appendInst( |
- Ice::InstStore::create(Func, Value, Address, Alignment)); |
+ Ice::InstStore::create(Func.get(), Value, Address, Alignment)); |
return; |
} |
case naclbitc::FUNC_CODE_INST_CALL: |
@@ -2459,10 +2469,11 @@ void FunctionParser::ProcessRecord() { |
: getNextInstVar(ReturnType); |
Ice::InstCall *Inst = nullptr; |
if (IntrinsicInfo) { |
- Inst = Ice::InstIntrinsicCall::create(Func, NumParams, Dest, Callee, |
+ Inst = Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest, Callee, |
IntrinsicInfo->Info); |
} else { |
- Inst = Ice::InstCall::create(Func, NumParams, Dest, Callee, IsTailCall); |
+ Inst = Ice::InstCall::create(Func.get(), NumParams, Dest, Callee, |
+ IsTailCall); |
} |
// Add parameters. |
@@ -2857,7 +2868,7 @@ bool ModuleParser::ParseBlock(unsigned BlockID) { |
case naclbitc::FUNCTION_BLOCK_ID: { |
InstallGlobalNamesAndGlobalVarInitializers(); |
FunctionParser Parser(BlockID, this); |
- return Parser.ParseThisBlock(); |
+ return Parser.convertFunction(); |
} |
default: |
return BlockParserBaseClass::ParseBlock(BlockID); |