12469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/*
22469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * Copyright (C) 2014 The Android Open Source Project
32469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler *
42469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * Licensed under the Apache License, Version 2.0 (the "License");
52469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * you may not use this file except in compliance with the License.
62469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * You may obtain a copy of the License at
72469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler *
82469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler *      http://www.apache.org/licenses/LICENSE-2.0
92469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler *
102469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * Unless required by applicable law or agreed to in writing, software
112469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * distributed under the License is distributed on an "AS IS" BASIS,
122469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * See the License for the specific language governing permissions and
142469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * limitations under the License.
152469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
162469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
17fd5a852e49796374899772381f15c9033dae0057Narayan Kamath#ifndef ART_COMPILER_DEX_POST_OPT_PASSES_H_
18fd5a852e49796374899772381f15c9033dae0057Narayan Kamath#define ART_COMPILER_DEX_POST_OPT_PASSES_H_
192469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
200b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/casts.h"
210b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h"
220b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "compiler_ir.h"
230b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "dex_flags.h"
240b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "mir_graph.h"
252469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler#include "pass_me.h"
262469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
272469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylernamespace art {
282469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
292469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
30ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko * @class PassMEMirSsaRep
31ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko * @brief Convenience class for passes that check MIRGraph::MirSsaRepUpToDate().
32ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko */
33ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass PassMEMirSsaRep : public PassME {
34ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko public:
35ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  PassMEMirSsaRep(const char* name, DataFlowAnalysisMode type = kAllNodes)
36ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko      : PassME(name, type) {
37ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  }
38ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko
39ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  bool Gate(const PassDataHolder* data) const OVERRIDE {
40ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(data != nullptr);
41ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
42ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(c_unit != nullptr);
43ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    return !c_unit->mir_graph->MirSsaRepUpToDate();
44ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  }
45ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko};
46ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko
47ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko/**
48ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko * @class InitializeSSATransformation
492469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief There is some data that needs to be initialized before performing
502469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * the post optimization passes.
512469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
52ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass InitializeSSATransformation : public PassMEMirSsaRep {
532469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
54ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  InitializeSSATransformation() : PassMEMirSsaRep("InitializeSSATransformation", kNoNodes) {
552469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
562469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
57e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
582469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    // New blocks may have been inserted so the first thing we do is ensure that
592469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    // the c_unit's number of blocks matches the actual count of basic blocks.
602469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
61e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
622469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
63ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    c_unit->mir_graph->SSATransformationStart();
64ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    c_unit->mir_graph->CompilerInitializeSSAConversion();
652469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
662469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
672469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
682469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
692469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class ClearPhiInformation
702469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Clear the PHI nodes from the CFG.
712469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
72ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass ClearPhiInstructions : public PassMEMirSsaRep {
732469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
74ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  ClearPhiInstructions() : PassMEMirSsaRep("ClearPhiInstructions") {
752469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
762469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
7709321dfb4803669ba6d6f3fef6363a1fd7202eeaJean Christophe Beyler  bool Worker(PassDataHolder* data) const;
782469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
792469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
802469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
812469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class CalculatePredecessors
822469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Calculate the predecessor BitVector of each Basicblock.
832469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
842469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylerclass CalculatePredecessors : public PassME {
852469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
86aa7b8a329561c6e1f05938ddc5e9c4be795cd8a5Vladimir Marko  CalculatePredecessors() : PassME("CalculatePredecessors", kNoNodes) {
872469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
882469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
89e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const;
902469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
912469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
922469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
932469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class DFSOrders
942469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Compute the DFS order of the MIR graph
952469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
962469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylerclass DFSOrders : public PassME {
972469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
98aa7b8a329561c6e1f05938ddc5e9c4be795cd8a5Vladimir Marko  DFSOrders() : PassME("DFSOrders", kNoNodes) {
992469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1002469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
101312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko  bool Gate(const PassDataHolder* data) const {
102312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko    DCHECK(data != nullptr);
103312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko    CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
104312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko    DCHECK(c_unit != nullptr);
105312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko    return !c_unit->mir_graph->DfsOrdersUpToDate();
106312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko  }
107312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko
108e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
1092469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
110e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
1112469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
1122469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    c_unit->mir_graph.get()->ComputeDFSOrders();
1132469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1142469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
1152469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
1162469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
1172469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class BuildDomination
1182469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Build the domination information of the MIR Graph
1192469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
1202469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylerclass BuildDomination : public PassME {
1212469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
122aa7b8a329561c6e1f05938ddc5e9c4be795cd8a5Vladimir Marko  BuildDomination() : PassME("BuildDomination", kNoNodes) {
1232469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1242469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
125ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  bool Gate(const PassDataHolder* data) const {
126ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(data != nullptr);
127ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
128ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(c_unit != nullptr);
129ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    return !c_unit->mir_graph->DominationUpToDate();
130ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  }
131ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko
132e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
1332469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
134e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
1352469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
136ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    c_unit->mir_graph->ComputeDominators();
1372469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1382469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
139e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void End(PassDataHolder* data) const {
1402469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
141e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
1422469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
1432469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    // Verify the dataflow information after the pass.
1442469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    if (c_unit->enable_debug & (1 << kDebugVerifyDataflow)) {
1452469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      c_unit->mir_graph->VerifyDataflow();
1462469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    }
1472469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1482469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
1492469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
1502469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
151622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko * @class TopologicalSortOrders
152622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko * @brief Compute the topological sort order of the MIR graph
153622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko */
154622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Markoclass TopologicalSortOrders : public PassME {
155622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko public:
156aa7b8a329561c6e1f05938ddc5e9c4be795cd8a5Vladimir Marko  TopologicalSortOrders() : PassME("TopologicalSortOrders", kNoNodes) {
157622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko  }
158622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko
159ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  bool Gate(const PassDataHolder* data) const {
160ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(data != nullptr);
161ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
162ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    DCHECK(c_unit != nullptr);
163ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    return !c_unit->mir_graph->TopologicalOrderUpToDate();
164ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  }
165ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko
166622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko  void Start(PassDataHolder* data) const {
167622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko    DCHECK(data != nullptr);
168622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
169622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko    DCHECK(c_unit != nullptr);
170622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko    c_unit->mir_graph.get()->ComputeTopologicalSortOrder();
171622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko  }
172622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko};
173622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko
174622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko/**
1752469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class DefBlockMatrix
1762469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Calculate the matrix of definition per basic block
1772469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
178ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass DefBlockMatrix : public PassMEMirSsaRep {
1792469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
180ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  DefBlockMatrix() : PassMEMirSsaRep("DefBlockMatrix", kNoNodes) {
1812469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1822469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
183e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
1842469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
185e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
1862469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
1872469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    c_unit->mir_graph.get()->ComputeDefBlockMatrix();
1882469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1892469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
1902469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
1912469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
1926a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko * @class FindPhiNodeBlocksPass
1936a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko * @brief Pass to find out where we need to insert the phi nodes for the SSA conversion.
1942469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
1956a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Markoclass FindPhiNodeBlocksPass : public PassMEMirSsaRep {
1962469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
1976a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko  FindPhiNodeBlocksPass() : PassMEMirSsaRep("FindPhiNodeBlocks", kNoNodes) {
1982469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
1992469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
200e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
2012469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
202e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
2032469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
2046a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko    c_unit->mir_graph.get()->FindPhiNodeBlocks();
2052469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2062469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
2072469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
2082469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
2092469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class SSAConversion
2102469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Pass for SSA conversion of MIRs
2112469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
212ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass SSAConversion : public PassMEMirSsaRep {
2132469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
214ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  SSAConversion() : PassMEMirSsaRep("SSAConversion", kNoNodes) {
2152469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2162469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
217e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
2182469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
219e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
2202469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
2212469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    MIRGraph *mir_graph = c_unit->mir_graph.get();
222ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko    mir_graph->ClearAllVisitedFlags();
2232469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    mir_graph->DoDFSPreOrderSSARename(mir_graph->GetEntryBlock());
2242469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2252469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
2262469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
2272469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
2282469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class PhiNodeOperands
2292469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Pass to insert the Phi node operands to basic blocks
2302469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
231ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass PhiNodeOperands : public PassMEMirSsaRep {
2322469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
233ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  PhiNodeOperands() : PassMEMirSsaRep("PhiNodeOperands", kPreOrderDFSTraversal) {
2342469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2352469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
23609321dfb4803669ba6d6f3fef6363a1fd7202eeaJean Christophe Beyler  bool Worker(PassDataHolder* data) const {
2372469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
23809321dfb4803669ba6d6f3fef6363a1fd7202eeaJean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
2392469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
24009321dfb4803669ba6d6f3fef6363a1fd7202eeaJean Christophe Beyler    BasicBlock* bb = down_cast<PassMEDataHolder*>(data)->bb;
2412469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(bb != nullptr);
2422469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    c_unit->mir_graph->InsertPhiNodeOperands(bb);
2432469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    // No need of repeating, so just return false.
2442469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    return false;
2452469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2462469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
2472469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
2482469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
2492469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @class InitRegLocations
2502469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief Initialize Register Locations.
2512469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
252ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass PerformInitRegLocations : public PassMEMirSsaRep {
2532469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
254ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  PerformInitRegLocations() : PassMEMirSsaRep("PerformInitRegLocation", kNoNodes) {
2552469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2562469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
257e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void Start(PassDataHolder* data) const {
2582469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
259e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
2602469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
2612469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    c_unit->mir_graph->InitRegLocations();
2622469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2632469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
2642469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
2652469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
266c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko * @class TypeInferencePass
267066f9e4b87d875f02a10fd43d8a251b3c17a64a3Vladimir Marko * @brief Type inference pass.
2682469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
269c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Markoclass TypeInferencePass : public PassMEMirSsaRep {
2702469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
271c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko  TypeInferencePass() : PassMEMirSsaRep("TypeInference", kRepeatingPreOrderDFSTraversal) {
272c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko  }
273c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko
274c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko  void Start(PassDataHolder* data) const {
275c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    DCHECK(data != nullptr);
276c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
277c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    DCHECK(c_unit != nullptr);
278c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    c_unit->mir_graph->InferTypesStart();
2792469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
2802469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
28109321dfb4803669ba6d6f3fef6363a1fd7202eeaJean Christophe Beyler  bool Worker(PassDataHolder* data) const {
2822469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
283066f9e4b87d875f02a10fd43d8a251b3c17a64a3Vladimir Marko    PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
284066f9e4b87d875f02a10fd43d8a251b3c17a64a3Vladimir Marko    CompilationUnit* c_unit = pass_me_data_holder->c_unit;
2852469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
286066f9e4b87d875f02a10fd43d8a251b3c17a64a3Vladimir Marko    BasicBlock* bb = pass_me_data_holder->bb;
2872469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(bb != nullptr);
288066f9e4b87d875f02a10fd43d8a251b3c17a64a3Vladimir Marko    return c_unit->mir_graph->InferTypes(bb);
2892469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
290c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko
291c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko  void End(PassDataHolder* data) const {
292c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    DCHECK(data != nullptr);
293c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
294c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    DCHECK(c_unit != nullptr);
295c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko    c_unit->mir_graph.get()->InferTypesEnd();
296c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko  }
2972469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
2982469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
2992469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler/**
300ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko * @class FinishSSATransformation
3012469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler * @brief There is some data that needs to be freed after performing the post optimization passes.
3022469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler */
303ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Markoclass FinishSSATransformation : public PassMEMirSsaRep {
3042469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler public:
305ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko  FinishSSATransformation() : PassMEMirSsaRep("FinishSSATransformation", kNoNodes) {
3062469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
3072469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
308e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler  void End(PassDataHolder* data) const {
3092469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(data != nullptr);
310e1f65bcb957a65c6d45b319d968bc53a833f2c65Jean Christophe Beyler    CompilationUnit* c_unit = down_cast<PassMEDataHolder*>(data)->c_unit;
3112469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    DCHECK(c_unit != nullptr);
3122469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler    c_unit->mir_graph.get()->SSATransformationEnd();
3132469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler  }
3142469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler};
3152469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
3162469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler}  // namespace art
3172469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler
318fd5a852e49796374899772381f15c9033dae0057Narayan Kamath#endif  // ART_COMPILER_DEX_POST_OPT_PASSES_H_
319