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/Target/TargetInstrInfo.h" 19 20 namespace llvm { 21 22 /// \brief Check if the instr pair, FirstMI and SecondMI, should be fused 23 /// together. Given SecondMI, when FirstMI is unspecified, then check if 24 /// SecondMI may be part of a fused pair at all. 25 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII, 26 const TargetSubtargetInfo &TSI, 27 const MachineInstr *FirstMI, 28 const MachineInstr &SecondMI) { 29 const ARMSubtarget &ST = static_cast<const ARMSubtarget&>(TSI); 30 31 // Assume wildcards for unspecified instrs. 32 unsigned FirstOpcode = 33 FirstMI ? FirstMI->getOpcode() 34 : static_cast<unsigned>(ARM::INSTRUCTION_LIST_END); 35 unsigned SecondOpcode = SecondMI.getOpcode(); 36 37 if (ST.hasFuseAES()) 38 // Fuse AES crypto operations. 39 switch(SecondOpcode) { 40 // AES encode. 41 case ARM::AESMC : 42 return FirstOpcode == ARM::AESE || 43 FirstOpcode == ARM::INSTRUCTION_LIST_END; 44 // AES decode. 45 case ARM::AESIMC: 46 return FirstOpcode == ARM::AESD || 47 FirstOpcode == ARM::INSTRUCTION_LIST_END; 48 } 49 50 return false; 51 } 52 53 std::unique_ptr<ScheduleDAGMutation> createARMMacroFusionDAGMutation () { 54 return createMacroFusionDAGMutation(shouldScheduleAdjacent); 55 } 56 57 } // end namespace llvm 58