blob: 0bc5b87de150059fdf1e9037dd0b08b463583e82 [file] [log] [blame]
Aditya Nandakumar81c81b62018-01-25 00:41:58 +00001//===-- lib/CodeGen/GlobalISel/GICombiner.cpp -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file constains common code to combine machine functions at generic
11// level.
12//===----------------------------------------------------------------------===//
13
14#include "llvm/CodeGen/GlobalISel/Combiner.h"
15#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
16#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
18#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
19#include "llvm/ADT/PostOrderIterator.h"
20#include "llvm/CodeGen/GlobalISel/Utils.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/Support/Debug.h"
23
24#define DEBUG_TYPE "gi-combiner"
25
26using namespace llvm;
27
28Combiner::Combiner(CombinerInfo &Info, const TargetPassConfig *TPC)
29 : CInfo(Info), TPC(TPC) {
30 (void)this->TPC; // FIXME: Remove when used.
31}
32
33bool Combiner::combineMachineInstrs(MachineFunction &MF) {
34 // If the ISel pipeline failed, do not bother running this pass.
35 // FIXME: Should this be here or in individual combiner passes.
36 if (MF.getProperties().hasProperty(
37 MachineFunctionProperties::Property::FailedISel))
38 return false;
39
40 MRI = &MF.getRegInfo();
41 Builder.setMF(MF);
42
Nicola Zaghend34e60c2018-05-14 12:53:11 +000043 LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');
Aditya Nandakumar81c81b62018-01-25 00:41:58 +000044
45 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
46
47 bool MFChanged = false;
48 bool Changed;
49
50 do {
51 // Collect all instructions. Do a post order traversal for basic blocks and
52 // insert with list bottom up, so while we pop_back_val, we'll traverse top
53 // down RPOT.
54 Changed = false;
55 GISelWorkList<512> WorkList;
56 for (MachineBasicBlock *MBB : post_order(&MF)) {
57 if (MBB->empty())
58 continue;
59 for (auto MII = MBB->rbegin(), MIE = MBB->rend(); MII != MIE;) {
60 MachineInstr *CurMI = &*MII;
61 ++MII;
62 // Erase dead insts before even adding to the list.
63 if (isTriviallyDead(*CurMI, *MRI)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +000064 LLVM_DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
Aditya Nandakumar81c81b62018-01-25 00:41:58 +000065 CurMI->eraseFromParentAndMarkDBGValuesForRemoval();
66 continue;
67 }
68 WorkList.insert(CurMI);
69 }
70 }
71 // Main Loop. Process the instructions here.
72 while (!WorkList.empty()) {
73 MachineInstr *CurrInst = WorkList.pop_back_val();
Nicola Zaghend34e60c2018-05-14 12:53:11 +000074 LLVM_DEBUG(dbgs() << "Try combining " << *CurrInst << "\n";);
Daniel Sanders33f42f92018-10-01 22:32:08 +000075 Changed |= CInfo.combine(*CurrInst, Builder);
Aditya Nandakumar81c81b62018-01-25 00:41:58 +000076 }
77 MFChanged |= Changed;
78 } while (Changed);
79
80 return MFChanged;
81}