From 76719b4aab9bdc44a9d37004aba64471790ab574 Mon Sep 17 00:00:00 2001 From: Jim Stichnoth Date: Mon, 14 Mar 2016 08:37:52 -0700 Subject: [PATCH] Subzero: Control whether deleted instructions are retained. Normally, deleted instructions are preserved in the Cfg, and printed as part of dump output. This helps debugging by partially explaining the provenance of new instructions that originated from the deleted instructions. However, these instructions slow down iteration over the instruction list, and checking their deleted status may pollute the cache. As such, in a non-DUMP enabled build, we repurpose the renumberInstructions() pass to also unlink deleted instructions as needed. A flag is provided to override this behavior, in case we have to debug a situation where a bug only manifests in a DUMP build and not a non-DUMP build, or vice versa. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4360 R=eholk@chromium.org, jpp@chromium.org Review URL: https://codereview.chromium.org/1790063003 . --- src/IceCfg.h | 8 ++++++++ src/IceCfgNode.cpp | 25 +++++++++++++++++-------- src/IceClFlags.cpp | 10 ++++++++++ src/IceClFlags.h | 7 +++++++ src/IceDefs.h | 2 +- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/IceCfg.h b/src/IceCfg.h index d3aabe939..88178fd1b 100644 --- a/src/IceCfg.h +++ b/src/IceCfg.h @@ -185,6 +185,14 @@ public: /// predecessor and successor edges, in the form of CfgNode::InEdges[] and /// CfgNode::OutEdges[]. void computeInOutEdges(); + /// Renumber the non-deleted instructions in the Cfg. This needs to be done + /// in preparation for live range analysis. The instruction numbers in a + /// block must be monotonically increasing. The range of instruction numbers + /// in a block, from lowest to highest, must not overlap with the range of any + /// other block. + /// + /// Also, if the configuration specifies to do so, remove/unlink all deleted + /// instructions from the Cfg, to speed up later passes over the instructions. void renumberInstructions(); void placePhiLoads(); void placePhiStores(); diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp index 0729585bf..212f742c5 100644 --- a/src/IceCfgNode.cpp +++ b/src/IceCfgNode.cpp @@ -52,16 +52,25 @@ void CfgNode::appendInst(Inst *Instr) { } } -// Renumbers the non-deleted instructions in the node. This needs to be done in -// preparation for live range analysis. The instruction numbers in a block must -// be monotonically increasing. The range of instruction numbers in a block, -// from lowest to highest, must not overlap with the range of any other block. +namespace { +template void removeDeletedAndRenumber(List *L, Cfg *Func) { + const bool DoDelete = + BuildDefs::minimal() || !GlobalContext::getFlags().getKeepDeletedInsts(); + auto I = L->begin(), E = L->end(), Next = I; + for (++Next; I != E; I = Next++) { + if (DoDelete && I->isDeleted()) { + L->erase(I); + } else { + I->renumber(Func); + } + } +} +} // end of anonymous namespace + void CfgNode::renumberInstructions() { InstNumberT FirstNumber = Func->getNextInstNumber(); - for (Inst &I : Phis) - I.renumber(Func); - for (Inst &I : Insts) - I.renumber(Func); + removeDeletedAndRenumber(&Phis, Func); + removeDeletedAndRenumber(&Insts, Func); InstCountEstimate = Func->getNextInstNumber() - FirstNumber; } diff --git a/src/IceClFlags.cpp b/src/IceClFlags.cpp index e21413c4e..b944ec0f5 100644 --- a/src/IceClFlags.cpp +++ b/src/IceClFlags.cpp @@ -136,6 +136,14 @@ cl::opt FunctionSections("ffunction-sections", cl::desc("Emit functions into separate sections")); +/// Retain deleted instructions in the Cfg. Defaults to true in DUMP-enabled +/// build, and false in a non-DUMP build, but is ignored in a MINIMAL build. +/// This flag allows overriding the default primarily for debugging. +cl::opt + KeepDeletedInsts("keep-deleted-insts", + cl::desc("Retain deleted instructions in the Cfg"), + cl::init(Ice::BuildDefs::dump())); + /// Mock bounds checking on loads/stores. cl::opt MockBoundsCheck("mock-bounds-check", cl::desc("Mock bounds checking on loads/stores")); @@ -475,6 +483,7 @@ void ClFlags::resetClFlags(ClFlags &OutFlags) { OutFlags.ForceMemIntrinOpt = false; OutFlags.FunctionSections = false; OutFlags.GenerateUnitTestMessages = false; + OutFlags.KeepDeletedInsts = Ice::BuildDefs::dump(); OutFlags.MockBoundsCheck = false; OutFlags.PhiEdgeSplit = false; OutFlags.RandomNopInsertion = false; @@ -544,6 +553,7 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) { OutFlags.setFunctionSections(::FunctionSections); OutFlags.setNumTranslationThreads(::NumThreads); OutFlags.setOptLevel(::OLevel); + OutFlags.setKeepDeletedInsts(::KeepDeletedInsts); OutFlags.setMockBoundsCheck(::MockBoundsCheck); OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit); OutFlags.setRandomSeed(::RandomSeed); diff --git a/src/IceClFlags.h b/src/IceClFlags.h index d10c8c4d2..971ad9d7a 100644 --- a/src/IceClFlags.h +++ b/src/IceClFlags.h @@ -164,6 +164,11 @@ public: GenerateUnitTestMessages = NewValue; } + /// Get the value of ClFlags::KeepDeletedInsts + bool getKeepDeletedInsts() const { return KeepDeletedInsts; } + /// Set ClFlags::KeepDeletedInsts to a new value + void setKeepDeletedInsts(bool NewValue) { KeepDeletedInsts = NewValue; } + /// Get the value of ClFlags::MockBoundsCheck bool getMockBoundsCheck() const { return MockBoundsCheck; } /// Set ClFlags::MockBoundsCheck to a new value @@ -437,6 +442,8 @@ private: bool FunctionSections; /// Initialized to false; not set by the command line. bool GenerateUnitTestMessages; + /// see anonymous_namespace{IceClFlags.cpp}::KeepDeletedInsts + bool KeepDeletedInsts; /// see anonymous_namespace{IceClFlags.cpp}::MockBoundsCheck bool MockBoundsCheck; /// see anonymous_namespace{IceClFlags.cpp}::EnablePhiEdgeSplit diff --git a/src/IceDefs.h b/src/IceDefs.h index d9c0c2347..2b19b3f51 100644 --- a/src/IceDefs.h +++ b/src/IceDefs.h @@ -222,7 +222,7 @@ enum VerboseItem { IceV_ConstPoolStats = 1 << 23, IceV_All = ~IceV_None, IceV_Most = - IceV_All & ~IceV_LinearScan & ~IceV_GlobalInit & IceV_ConstPoolStats + IceV_All & ~IceV_LinearScan & ~IceV_GlobalInit & ~IceV_ConstPoolStats }; using VerboseMask = uint32_t; -- 2.11.0