LLVM: lib/CodeGen/MacroFusion.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

24

25#define DEBUG_TYPE "machine-scheduler"

26

27STATISTIC(NumFused, "Number of instr pairs fused");

28

29using namespace llvm;

30

32 cl::desc("Enable scheduling for macro fusion."), cl::init(true));

33

37

40 if (SI.isCluster())

41 return SI.getSUnit();

42

43 return nullptr;

44}

45

47 unsigned Num = 1;

48 const SUnit *CurrentSU = &SU;

49 while ((CurrentSU = getPredClusterSU(*CurrentSU)) && Num < FuseLimit) Num ++;

50 return Num < FuseLimit;

51}

52

54 SUnit &SecondSU) {

55

56

58 if (SI.isCluster())

59 return false;

60

62 if (SI.isCluster())

63 return false;

64

67

68

69

70

71

72

73

75 return false;

76

78

81

83 Clusters.push_back(Cluster);

84

85

86

87

88

89

91 "Currently we only support chaining together two instructions");

92

93

95 if (SI.getSUnit() == &SecondSU)

96 SI.setLatency(0);

97

99 if (SI.getSUnit() == &FirstSU)

100 SI.setLatency(0);

101

107

108

109

110 if (&SecondSU != &DAG.ExitSU)

112 SUnit *SU = SI.getSUnit();

114 SU == &DAG.ExitSU || SU == &SecondSU || SU->isPred(&SecondSU))

115 continue;

119 }

120

121

122

123 if (&FirstSU != &DAG.EntrySU) {

125 SUnit *SU = SI.getSUnit();

126 if (SI.isWeak() || isHazard(SI) || &FirstSU == SU || FirstSU.isSucc(SU))

127 continue;

131 }

132

133

134

135 if (&SecondSU == &DAG.ExitSU) {

137 if (SU.Succs.empty())

139 }

140 }

141 }

142

143 ++NumFused;

144 return true;

145}

146

147namespace {

148

149

150

152 std::vector Predicates;

153 bool FuseBlock;

155

156public:

158 : Predicates(Predicates.begin(), Predicates.end()), FuseBlock(FuseBlock) {

159 }

160

161 void apply(ScheduleDAGInstrs *DAGInstrs) override;

162

164 const TargetSubtargetInfo &STI,

165 const MachineInstr *FirstMI,

166 const MachineInstr &SecondMI);

167};

168

169}

170

176 return Predicate(TII, STI, FirstMI, SecondMI);

177 });

178}

179

180void MacroFusion::apply(ScheduleDAGInstrs *DAG) {

181 if (FuseBlock)

182

183

184 for (SUnit &ISU : DAG->SUnits)

185 scheduleAdjacentImpl(*DAG, ISU);

186

188

189 scheduleAdjacentImpl(*DAG, DAG->ExitSU);

190}

191

192

193

194bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU) {

195 const MachineInstr &AnchorMI = *AnchorSU.getInstr();

196 const TargetInstrInfo &TII = *DAG.TII;

198

199

201 return false;

202

203

204 for (SDep &Dep : AnchorSU.Preds) {

205

207 continue;

208

209 SUnit &DepSU = *Dep.getSUnit();

211 continue;

212

213

214 const MachineInstr *DepMI = DepSU.getInstr();

217 continue;

218

220 return true;

221 }

222

223 return false;

224}

225

226std::unique_ptr

228 bool BranchOnly) {

230 return std::make_unique(Predicates, !BranchOnly);

231 return nullptr;

232}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)

Check if the instr pair, FirstMI and SecondMI, should be fused together.

const TargetInstrInfo & TII

static cl::opt< bool > EnableMacroFusion("misched-fusion", cl::Hidden, cl::desc("Enable scheduling for macro fusion."), cl::init(true))

static SUnit * getPredClusterSU(const SUnit &SU)

Definition MacroFusion.cpp:38

static bool isHazard(const SDep &Dep)

Definition MacroFusion.cpp:34

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

StringRef getName(unsigned Opcode) const

Returns the name for the instructions with the given opcode.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

Kind getKind() const

Returns an enum value representing the kind of the dependence.

@ Output

A register output-dependence (aka WAW).

@ Anti

A register anti-dependence (aka WAR).

bool isWeak() const

Tests if this a weak dependence.

@ Cluster

Weak DAG edge linking a chain of clustered instrs.

@ Artificial

Arbitrary strong DAG edge (no real dependence).

Scheduling unit. This is a node in the scheduling DAG.

bool isSucc(const SUnit *N) const

Tests if node N is a successor of this node.

bool isPred(const SUnit *N) const

Tests if node N is a predecessor of this node.

bool isBoundaryNode() const

Boundary nodes are placeholders for the boundary of the scheduling region.

unsigned ParentClusterIdx

The parent cluster id.

SmallVector< SDep, 4 > Succs

All sunit successors.

SmallVector< SDep, 4 > Preds

All sunit predecessors.

MachineInstr * getInstr() const

Returns the representative MachineInstr for this SUnit.

A ScheduleDAG for scheduling lists of MachineInstr.

SmallVector< ClusterInfo > & getClusters()

Returns the array of the clusters.

bool addEdge(SUnit *SuccSU, const SDep &PredDep)

Add a DAG edge to the given SU with the given predecessor dependence data.

Mutate the DAG as a postpass after normal DAG building.

const TargetInstrInfo * TII

Target instruction information.

std::vector< SUnit > SUnits

The scheduling units.

SUnit EntrySU

Special node for the region entry.

MachineFunction & MF

Machine function.

void dumpNodeName(const SUnit &SU) const

SUnit ExitSU

Special node for the region exit.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

TargetInstrInfo - Interface to description of machine instruction set.

TargetSubtargetInfo - Generic base class for all target subtargets.

Predicate

Predicate - These are "(BI << 5) | BO" for various predicates.

void apply(Opt *O, const Mod &M, const Mods &... Ms)

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(ArrayRef< MacroFusionPredTy > Predicates, bool BranchOnly=false)

Create a DAG scheduling mutation to pair instructions back to back for instructions that benefit acco...

Definition MacroFusion.cpp:227

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI bool fuseInstructionPair(ScheduleDAGInstrs &DAG, SUnit &FirstSU, SUnit &SecondSU)

Create an artificial edge between FirstSU and SecondSU.

Definition MacroFusion.cpp:53

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

constexpr unsigned InvalidClusterId

bool(*)(const TargetInstrInfo &TII, const TargetSubtargetInfo &STI, const MachineInstr *FirstMI, const MachineInstr &SecondMI) MacroFusionPredTy

Check if the instr pair, FirstMI and SecondMI, should be fused together.

static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, const TargetSubtargetInfo &TSI, const MachineInstr *FirstMI, const MachineInstr &SecondMI)

Check if the instr pair, FirstMI and SecondMI, should be fused together.

LLVM_ABI bool hasLessThanNumFused(const SUnit &SU, unsigned FuseLimit)

Checks if the number of cluster edges between SU and its predecessors is less than FuseLimit.

Definition MacroFusion.cpp:46