Subzero: Manage each Cfg as a std::unique_ptr<Cfg>. The Cfg::create() method now returns a unique_ptr. Once the parser fully builds the Cfg, it is released onto the work queue, and then acquired and ultimately deleted by the translator thread. BUG= none R=jfb@chromium.org Review URL: https://codereview.chromium.org/892063002
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp index 53f9a9f..b284d06 100644 --- a/src/IceCfg.cpp +++ b/src/IceCfg.cpp
@@ -46,11 +46,7 @@ "Attempt to build cfg when IR generation disabled"); } -Cfg::~Cfg() { - assert(ICE_TLS_GET_FIELD(CurrentCfg) == this); - // Reset the thread-local CurrentCfg pointer. - ICE_TLS_SET_FIELD(CurrentCfg, nullptr); -} +Cfg::~Cfg() { assert(ICE_TLS_GET_FIELD(CurrentCfg) == nullptr); } void Cfg::setError(const IceString &Message) { HasError = true;
diff --git a/src/IceCfg.h b/src/IceCfg.h index 71f0a0d..605dcf7 100644 --- a/src/IceCfg.h +++ b/src/IceCfg.h
@@ -30,17 +30,14 @@ public: ~Cfg(); - // TODO(stichnot): Change this to return unique_ptr<Cfg>, and plumb - // it through the callers, to make ownership and lifetime and - // destruction requirements more explicit. - static Cfg *create(GlobalContext *Ctx) { - Cfg *Func = new Cfg(Ctx); - ICE_TLS_SET_FIELD(CurrentCfg, Func); - return Func; + static std::unique_ptr<Cfg> create(GlobalContext *Ctx) { + return std::unique_ptr<Cfg>(new Cfg(Ctx)); } // Gets a pointer to the current thread's Cfg. static const Cfg *getCurrentCfg() { return ICE_TLS_GET_FIELD(CurrentCfg); } - void updateTLS() const { ICE_TLS_SET_FIELD(CurrentCfg, this); } + static void setCurrentCfg(const Cfg *Func) { + ICE_TLS_SET_FIELD(CurrentCfg, Func); + } // Gets a pointer to the current thread's Cfg's allocator. static ArenaAllocator<> *getCurrentCfgAllocator() { assert(ICE_TLS_GET_FIELD(CurrentCfg));
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp index e8ec56d..47f8b39 100644 --- a/src/IceConverter.cpp +++ b/src/IceConverter.cpp
@@ -48,6 +48,10 @@ } // Base class for converting LLVM to ICE. +// TODO(stichnot): Redesign Converter, LLVM2ICEConverter, +// LLVM2ICEFunctionConverter, and LLVM2ICEGlobalsConverter with +// respect to Translator. In particular, the unique_ptr ownership +// rules in LLVM2ICEFunctionConverter. class LLVM2ICEConverter { LLVM2ICEConverter(const LLVM2ICEConverter &) = delete; LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete; @@ -79,15 +83,16 @@ LLVM2ICEFunctionConverter(Ice::Converter &Converter) : LLVM2ICEConverter(Converter), Func(nullptr) {} - // Caller is expected to delete the returned Ice::Cfg object. - Ice::Cfg *convertFunction(const Function *F) { + void convertFunction(const Function *F) { + Func = Ice::Cfg::create(Ctx); + Ice::Cfg::setCurrentCfg(Func.get()); + VarMap.clear(); NodeMap.clear(); - Func = Ice::Cfg::create(Ctx); Func->setFunctionName(F->getName()); Func->setReturnType(convertToIceType(F->getReturnType())); Func->setInternal(F->hasInternalLinkage()); - Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func); + Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func.get()); // The initial definition/use of each arg is the entry node. for (auto ArgI = F->arg_begin(), ArgE = F->arg_end(); ArgI != ArgE; @@ -106,7 +111,8 @@ Func->setEntryNode(mapBasicBlockToNode(&F->getEntryBlock())); Func->computePredecessors(); - return Func; + Ice::Cfg::setCurrentCfg(nullptr); + Converter.translateFcn(std::move(Func)); } // convertConstant() does not use Func or require it to be a valid @@ -147,7 +153,7 @@ if (VarMap.find(V) == VarMap.end()) { VarMap[V] = Func->makeVariable(IceTy); if (ALLOW_DUMP) - VarMap[V]->setName(Func, V->getName()); + VarMap[V]->setName(Func.get(), V->getName()); } return VarMap[V]; } @@ -304,13 +310,13 @@ Ice::Inst *convertLoadInstruction(const LoadInst *Inst) { Ice::Operand *Src = convertOperand(Inst, 0); Ice::Variable *Dest = mapValueToIceVar(Inst); - return Ice::InstLoad::create(Func, Dest, Src); + return Ice::InstLoad::create(Func.get(), Dest, Src); } Ice::Inst *convertStoreInstruction(const StoreInst *Inst) { Ice::Operand *Addr = convertOperand(Inst, 1); Ice::Operand *Val = convertOperand(Inst, 0); - return Ice::InstStore::create(Func, Val, Addr); + return Ice::InstStore::create(Func.get(), Val, Addr); } Ice::Inst *convertArithInstruction(const Instruction *Inst, @@ -319,13 +325,13 @@ Ice::Operand *Src0 = convertOperand(Inst, 0); Ice::Operand *Src1 = convertOperand(Inst, 1); Ice::Variable *Dest = mapValueToIceVar(BinOp); - return Ice::InstArithmetic::create(Func, Opcode, Dest, Src0, Src1); + return Ice::InstArithmetic::create(Func.get(), Opcode, Dest, Src0, Src1); } Ice::Inst *convertPHINodeInstruction(const PHINode *Inst) { unsigned NumValues = Inst->getNumIncomingValues(); Ice::InstPhi *IcePhi = - Ice::InstPhi::create(Func, NumValues, mapValueToIceVar(Inst)); + Ice::InstPhi::create(Func.get(), NumValues, mapValueToIceVar(Inst)); for (unsigned N = 0, E = NumValues; N != E; ++N) { IcePhi->addArgument(convertOperand(Inst, N), mapBasicBlockToNode(Inst->getIncomingBlock(N))); @@ -340,31 +346,31 @@ BasicBlock *BBElse = Inst->getSuccessor(1); Ice::CfgNode *NodeThen = mapBasicBlockToNode(BBThen); Ice::CfgNode *NodeElse = mapBasicBlockToNode(BBElse); - return Ice::InstBr::create(Func, Src, NodeThen, NodeElse); + return Ice::InstBr::create(Func.get(), Src, NodeThen, NodeElse); } else { BasicBlock *BBSucc = Inst->getSuccessor(0); - return Ice::InstBr::create(Func, mapBasicBlockToNode(BBSucc)); + return Ice::InstBr::create(Func.get(), mapBasicBlockToNode(BBSucc)); } } Ice::Inst *convertIntToPtrInstruction(const IntToPtrInst *Inst) { Ice::Operand *Src = convertOperand(Inst, 0); Ice::Variable *Dest = mapValueToIceVar(Inst, Ice::getPointerType()); - return Ice::InstAssign::create(Func, Dest, Src); + return Ice::InstAssign::create(Func.get(), Dest, Src); } Ice::Inst *convertPtrToIntInstruction(const PtrToIntInst *Inst) { Ice::Operand *Src = convertOperand(Inst, 0); Ice::Variable *Dest = mapValueToIceVar(Inst); - return Ice::InstAssign::create(Func, Dest, Src); + return Ice::InstAssign::create(Func.get(), Dest, Src); } Ice::Inst *convertRetInstruction(const ReturnInst *Inst) { Ice::Operand *RetOperand = convertOperand(Inst, 0); if (RetOperand) { - return Ice::InstRet::create(Func, RetOperand); + return Ice::InstRet::create(Func.get(), RetOperand); } else { - return Ice::InstRet::create(Func); + return Ice::InstRet::create(Func.get()); } } @@ -372,7 +378,7 @@ Ice::InstCast::OpKind CastKind) { Ice::Operand *Src = convertOperand(Inst, 0); Ice::Variable *Dest = mapValueToIceVar(Inst); - return Ice::InstCast::create(Func, CastKind, Dest, Src); + return Ice::InstCast::create(Func.get(), CastKind, Dest, Src); } Ice::Inst *convertICmpInstruction(const ICmpInst *Inst) { @@ -416,7 +422,7 @@ break; } - return Ice::InstIcmp::create(Func, Cond, Dest, Src0, Src1); + return Ice::InstIcmp::create(Func.get(), Cond, Dest, Src0, Src1); } Ice::Inst *convertFCmpInstruction(const FCmpInst *Inst) { @@ -480,14 +486,14 @@ break; } - return Ice::InstFcmp::create(Func, Cond, Dest, Src0, Src1); + return Ice::InstFcmp::create(Func.get(), Cond, Dest, Src0, Src1); } Ice::Inst *convertExtractElementInstruction(const ExtractElementInst *Inst) { Ice::Variable *Dest = mapValueToIceVar(Inst); Ice::Operand *Source1 = convertValue(Inst->getOperand(0)); Ice::Operand *Source2 = convertValue(Inst->getOperand(1)); - return Ice::InstExtractElement::create(Func, Dest, Source1, Source2); + return Ice::InstExtractElement::create(Func.get(), Dest, Source1, Source2); } Ice::Inst *convertInsertElementInstruction(const InsertElementInst *Inst) { @@ -495,7 +501,7 @@ Ice::Operand *Source1 = convertValue(Inst->getOperand(0)); Ice::Operand *Source2 = convertValue(Inst->getOperand(1)); Ice::Operand *Source3 = convertValue(Inst->getOperand(2)); - return Ice::InstInsertElement::create(Func, Dest, Source1, Source2, + return Ice::InstInsertElement::create(Func.get(), Dest, Source1, Source2, Source3); } @@ -504,7 +510,7 @@ Ice::Operand *Cond = convertValue(Inst->getCondition()); Ice::Operand *Source1 = convertValue(Inst->getTrueValue()); Ice::Operand *Source2 = convertValue(Inst->getFalseValue()); - return Ice::InstSelect::create(Func, Dest, Cond, Source1, Source2); + return Ice::InstSelect::create(Func.get(), Dest, Cond, Source1, Source2); } Ice::Inst *convertSwitchInstruction(const SwitchInst *Inst) { @@ -512,7 +518,7 @@ Ice::CfgNode *LabelDefault = mapBasicBlockToNode(Inst->getDefaultDest()); unsigned NumCases = Inst->getNumCases(); Ice::InstSwitch *Switch = - Ice::InstSwitch::create(Func, NumCases, Source, LabelDefault); + Ice::InstSwitch::create(Func.get(), NumCases, Source, LabelDefault); unsigned CurrentCase = 0; for (SwitchInst::ConstCaseIt I = Inst->case_begin(), E = Inst->case_end(); I != E; ++I, ++CurrentCase) { @@ -544,14 +550,14 @@ report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") + LLVMObjectAsString(Inst)); } - NewInst = Ice::InstIntrinsicCall::create(Func, NumArgs, Dest, + NewInst = Ice::InstIntrinsicCall::create(Func.get(), NumArgs, Dest, CallTarget, Info->Info); } } // Not an intrinsic call. if (NewInst == nullptr) { - NewInst = Ice::InstCall::create(Func, NumArgs, Dest, CallTarget, + NewInst = Ice::InstCall::create(Func.get(), NumArgs, Dest, CallTarget, Inst->isTailCall()); } for (unsigned i = 0; i < NumArgs; ++i) { @@ -569,11 +575,11 @@ uint32_t Align = Inst->getAlignment(); Ice::Variable *Dest = mapValueToIceVar(Inst, Ice::getPointerType()); - return Ice::InstAlloca::create(Func, ByteCount, Align, Dest); + return Ice::InstAlloca::create(Func.get(), ByteCount, Align, Dest); } Ice::Inst *convertUnreachableInstruction(const UnreachableInst * /*Inst*/) { - return Ice::InstUnreachable::create(Func); + return Ice::InstUnreachable::create(Func.get()); } Ice::CfgNode *convertBasicBlock(const BasicBlock *BB) { @@ -621,7 +627,7 @@ private: // Data - Ice::Cfg *Func; + std::unique_ptr<Ice::Cfg> Func; std::map<const Value *, Ice::Variable *> VarMap; std::map<const BasicBlock *, Ice::CfgNode *> NodeMap; }; @@ -872,21 +878,21 @@ } void Converter::convertFunctions() { - TimerStackIdT StackID = GlobalContext::TSK_Funcs; + const TimerStackIdT StackID = GlobalContext::TSK_Funcs; for (const Function &I : *Mod) { if (I.empty()) continue; TimerIdT TimerID = 0; - if (ALLOW_DUMP && Ctx->getFlags().TimeEachFunction) { + const bool TimeThisFunction = + ALLOW_DUMP && Ctx->getFlags().TimeEachFunction; + if (TimeThisFunction) { TimerID = Ctx->getTimerID(StackID, I.getName()); Ctx->pushTimer(TimerID, StackID); } LLVM2ICEFunctionConverter FunctionConverter(*this); - - Cfg *Fcn = FunctionConverter.convertFunction(&I); - translateFcn(Fcn); - if (ALLOW_DUMP && Ctx->getFlags().TimeEachFunction) + FunctionConverter.convertFunction(&I); + if (TimeThisFunction) Ctx->popTimer(TimerID, StackID); } }
diff --git a/src/IceDefs.h b/src/IceDefs.h index 368e92c..19b0694 100644 --- a/src/IceDefs.h +++ b/src/IceDefs.h
@@ -23,6 +23,7 @@ #include <limits> #include <list> #include <map> +#include <memory> #include <mutex> #include <string> #include <system_error>
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp index 7b782e9..4324f97 100644 --- a/src/IceGlobalContext.cpp +++ b/src/IceGlobalContext.cpp
@@ -162,11 +162,11 @@ } void GlobalContext::translateFunctions() { - while (Cfg *Func = cfgQueueBlockingPop()) { + while (std::unique_ptr<Cfg> Func = cfgQueueBlockingPop()) { + // Install Func in TLS for Cfg-specific container allocators. + Cfg::setCurrentCfg(Func.get()); // Reset per-function stats being accumulated in TLS. resetStats(); - // Install Func in TLS for Cfg-specific container allocators. - Func->updateTLS(); // Set verbose level to none if the current function does NOT // match the -verbose-focus command-line option. if (!matchSymbolName(Func->getFunctionName(), getFlags().VerboseFocusOn)) @@ -191,10 +191,10 @@ Func->emit(); // TODO(stichnot): actually add to emit queue } - // TODO(stichnot): fix multithreaded stats dumping. dumpStats(Func->getFunctionName()); } - delete Func; + Cfg::setCurrentCfg(nullptr); + // The Cfg now gets deleted as Func goes out of scope. } } @@ -548,6 +548,19 @@ Timers->at(StackID).setName(NewName); } +// Note: cfgQueueBlockingPush and cfgQueueBlockingPop use unique_ptr +// at the interface to take and transfer ownership, but they +// internally store the raw Cfg pointer in the work queue. This +// allows e.g. future queue optimizations such as the use of atomics +// to modify queue elements. +void GlobalContext::cfgQueueBlockingPush(std::unique_ptr<Cfg> Func) { + CfgQ.blockingPush(Func.release()); +} + +std::unique_ptr<Cfg> GlobalContext::cfgQueueBlockingPop() { + return std::unique_ptr<Cfg>(CfgQ.blockingPop()); +} + void GlobalContext::dumpStats(const IceString &Name, bool Final) { if (!ALLOW_DUMP || !getFlags().DumpStats) return;
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h index 2bb8f62..e3e0810 100644 --- a/src/IceGlobalContext.h +++ b/src/IceGlobalContext.h
@@ -280,12 +280,12 @@ // queue. Notifies any idle workers that a new function is // available for translating. May block if the work queue is too // large, in order to control memory footprint. - void cfgQueueBlockingPush(Cfg *Func) { CfgQ.blockingPush(Func); } + void cfgQueueBlockingPush(std::unique_ptr<Cfg> Func); // Takes a Cfg from the work queue for translating. May block if // the work queue is currently empty. Returns nullptr if there is // no more work - the queue is empty and either end() has been // called or the Sequential flag was set. - Cfg *cfgQueueBlockingPop() { return CfgQ.blockingPop(); } + std::unique_ptr<Cfg> cfgQueueBlockingPop(); // Notifies that no more work will be added to the work queue. void cfgQueueNotifyEnd() { CfgQ.notifyEnd(); }
diff --git a/src/IceTranslator.cpp b/src/IceTranslator.cpp index c05f58d..4753b22 100644 --- a/src/IceTranslator.cpp +++ b/src/IceTranslator.cpp
@@ -53,8 +53,8 @@ return false; } -void Translator::translateFcn(Cfg *Func) { - Ctx->cfgQueueBlockingPush(Func); +void Translator::translateFcn(std::unique_ptr<Cfg> Func) { + Ctx->cfgQueueBlockingPush(std::move(Func)); if (Ctx->getFlags().NumTranslationThreads == 0) { Ctx->translateFunctions(); }
diff --git a/src/IceTranslator.h b/src/IceTranslator.h index cd5a8d6..6b35b25 100644 --- a/src/IceTranslator.h +++ b/src/IceTranslator.h
@@ -45,7 +45,7 @@ /// Translates the constructed ICE function Fcn to machine code. /// Takes ownership of Func. - void translateFcn(Cfg *Func); + void translateFcn(std::unique_ptr<Cfg> Func); /// Emits the constant pool. void emitConstants();
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp index 0c06231..249875f 100644 --- a/src/PNaClTranslator.cpp +++ b/src/PNaClTranslator.cpp
@@ -1052,19 +1052,27 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ return; if (isIRGenerationDisabled()) return; - CurrentNode->appendInst(Ice::InstUnreachable::create(Func)); + CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); InstIsTerminating = true; return; } @@ -2285,7 +2294,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ : 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 @@ case naclbitc::FUNCTION_BLOCK_ID: { InstallGlobalNamesAndGlobalVarInitializers(); FunctionParser Parser(BlockID, this); - return Parser.ParseThisBlock(); + return Parser.convertFunction(); } default: return BlockParserBaseClass::ParseBlock(BlockID);