1*0b57cec5SDimitry Andric //===--- RDFDeadCode.h ----------------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // RDF-based generic dead code elimination. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric // The main interface of this class are functions "collect" and "erase". 12*0b57cec5SDimitry Andric // This allows custom processing of the function being optimized by a 13*0b57cec5SDimitry Andric // particular consumer. The simplest way to use this class would be to 14*0b57cec5SDimitry Andric // instantiate an object, and then simply call "collect" and "erase", 15*0b57cec5SDimitry Andric // passing the result of "getDeadInstrs()" to it. 16*0b57cec5SDimitry Andric // A more complex scenario would be to call "collect" first, then visit 17*0b57cec5SDimitry Andric // all post-increment instructions to see if the address update is dead 18*0b57cec5SDimitry Andric // or not, and if it is, convert the instruction to a non-updating form. 19*0b57cec5SDimitry Andric // After that "erase" can be called with the set of nodes including both, 20*0b57cec5SDimitry Andric // dead defs from the updating instructions and the nodes corresponding 21*0b57cec5SDimitry Andric // to the dead instructions. 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric #ifndef RDF_DEADCODE_H 24*0b57cec5SDimitry Andric #define RDF_DEADCODE_H 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric #include "RDFGraph.h" 27*0b57cec5SDimitry Andric #include "RDFLiveness.h" 28*0b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric namespace llvm { 31*0b57cec5SDimitry Andric class MachineRegisterInfo; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric namespace rdf { 34*0b57cec5SDimitry Andric struct DeadCodeElimination { 35*0b57cec5SDimitry Andric DeadCodeElimination(DataFlowGraph &dfg, MachineRegisterInfo &mri) 36*0b57cec5SDimitry Andric : Trace(false), DFG(dfg), MRI(mri), LV(mri, dfg) {} 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric bool collect(); 39*0b57cec5SDimitry Andric bool erase(const SetVector<NodeId> &Nodes); 40*0b57cec5SDimitry Andric void trace(bool On) { Trace = On; } 41*0b57cec5SDimitry Andric bool trace() const { return Trace; } 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric SetVector<NodeId> getDeadNodes() { return DeadNodes; } 44*0b57cec5SDimitry Andric SetVector<NodeId> getDeadInstrs() { return DeadInstrs; } 45*0b57cec5SDimitry Andric DataFlowGraph &getDFG() { return DFG; } 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric private: 48*0b57cec5SDimitry Andric bool Trace; 49*0b57cec5SDimitry Andric SetVector<NodeId> LiveNodes; 50*0b57cec5SDimitry Andric SetVector<NodeId> DeadNodes; 51*0b57cec5SDimitry Andric SetVector<NodeId> DeadInstrs; 52*0b57cec5SDimitry Andric DataFlowGraph &DFG; 53*0b57cec5SDimitry Andric MachineRegisterInfo &MRI; 54*0b57cec5SDimitry Andric Liveness LV; 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric template<typename T> struct SetQueue; 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric bool isLiveInstr(const MachineInstr *MI) const; 59*0b57cec5SDimitry Andric void scanInstr(NodeAddr<InstrNode*> IA, SetQueue<NodeId> &WorkQ); 60*0b57cec5SDimitry Andric void processDef(NodeAddr<DefNode*> DA, SetQueue<NodeId> &WorkQ); 61*0b57cec5SDimitry Andric void processUse(NodeAddr<UseNode*> UA, SetQueue<NodeId> &WorkQ); 62*0b57cec5SDimitry Andric }; 63*0b57cec5SDimitry Andric } // namespace rdf 64*0b57cec5SDimitry Andric } // namespace llvm 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric #endif 67