Line data Source code
1 : //===- ARMMacroFusion.cpp - ARM Macro Fusion ----------------------===//
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 : /// \file This file contains the ARM implementation of the DAG scheduling
11 : /// mutation to pair instructions back to back.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "ARMMacroFusion.h"
16 : #include "ARMSubtarget.h"
17 : #include "llvm/CodeGen/MacroFusion.h"
18 : #include "llvm/CodeGen/TargetInstrInfo.h"
19 :
20 : namespace llvm {
21 :
22 : // Fuse AES crypto encoding or decoding.
23 136 : static bool isAESPair(const MachineInstr *FirstMI,
24 : const MachineInstr &SecondMI) {
25 : // Assume the 1st instr to be a wildcard if it is unspecified.
26 272 : switch(SecondMI.getOpcode()) {
27 : // AES encode.
28 20 : case ARM::AESMC :
29 20 : return FirstMI == nullptr || FirstMI->getOpcode() == ARM::AESE;
30 : // AES decode.
31 16 : case ARM::AESIMC:
32 16 : return FirstMI == nullptr || FirstMI->getOpcode() == ARM::AESD;
33 : }
34 :
35 : return false;
36 : }
37 :
38 : // Fuse literal generation.
39 : static bool isLiteralsPair(const MachineInstr *FirstMI,
40 : const MachineInstr &SecondMI) {
41 : // Assume the 1st instr to be a wildcard if it is unspecified.
42 44 : if ((FirstMI == nullptr || FirstMI->getOpcode() == ARM::MOVi16) &&
43 44 : SecondMI.getOpcode() == ARM::MOVTi16)
44 : return true;
45 :
46 : return false;
47 : }
48 :
49 : /// Check if the instr pair, FirstMI and SecondMI, should be fused
50 : /// together. Given SecondMI, when FirstMI is unspecified, then check if
51 : /// SecondMI may be part of a fused pair at all.
52 180 : static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
53 : const TargetSubtargetInfo &TSI,
54 : const MachineInstr *FirstMI,
55 : const MachineInstr &SecondMI) {
56 : const ARMSubtarget &ST = static_cast<const ARMSubtarget&>(TSI);
57 :
58 180 : if (ST.hasFuseAES() && isAESPair(FirstMI, SecondMI))
59 : return true;
60 144 : if (ST.hasFuseLiterals() && isLiteralsPair(FirstMI, SecondMI))
61 10 : return true;
62 :
63 : return false;
64 : }
65 :
66 7 : std::unique_ptr<ScheduleDAGMutation> createARMMacroFusionDAGMutation () {
67 7 : return createMacroFusionDAGMutation(shouldScheduleAdjacent);
68 : }
69 :
70 : } // end namespace llvm
|