1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
//===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements the info about Hexagon target spec.
//
//===----------------------------------------------------------------------===//
#include "HexagonTargetMachine.h"
#include "Hexagon.h"
#include "HexagonISelLowering.h"
#include "HexagonMachineScheduler.h"
#include "HexagonTargetObjectFile.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
static cl:: opt<bool> DisableHardwareLoops("disable-hexagon-hwloops",
cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target"));
static cl::opt<bool> DisableHexagonMISched("disable-hexagon-misched",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Hexagon MI Scheduling"));
static cl::opt<bool> DisableHexagonCFGOpt("disable-hexagon-cfgopt",
cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Disable Hexagon CFG Optimization"));
/// HexagonTargetMachineModule - Note that this is used on hosts that
/// cannot link in a library unless there are references into the
/// library. In particular, it seems that it is not possible to get
/// things to work on Win32 without this. Though it is unused, do not
/// remove it.
extern "C" int HexagonTargetMachineModule;
int HexagonTargetMachineModule = 0;
extern "C" void LLVMInitializeHexagonTarget() {
// Register the target.
RegisterTargetMachine<HexagonTargetMachine> X(TheHexagonTarget);
}
static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) {
return new VLIWMachineScheduler(C, make_unique<ConvergingVLIWScheduler>());
}
static MachineSchedRegistry
SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler",
createVLIWMachineSched);
/// HexagonTargetMachine ctor - Create an ILP32 architecture model.
///
/// Hexagon_TODO: Do I need an aggregate alignment?
///
HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, *this) {
initAsmInfo();
}
namespace {
/// Hexagon Code Generator Pass Configuration Options.
class HexagonPassConfig : public TargetPassConfig {
public:
HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
// FIXME: Rather than calling enablePass(&MachineSchedulerID) below, define
// HexagonSubtarget::enableMachineScheduler() { return true; }.
// That will bypass the SelectionDAG VLIW scheduler, which is probably just
// hurting compile time and will be removed eventually anyway.
if (DisableHexagonMISched)
disablePass(&MachineSchedulerID);
else
enablePass(&MachineSchedulerID);
}
HexagonTargetMachine &getHexagonTargetMachine() const {
return getTM<HexagonTargetMachine>();
}
ScheduleDAGInstrs *
createMachineScheduler(MachineSchedContext *C) const override {
return createVLIWMachineSched(C);
}
bool addInstSelector() override;
bool addPreRegAlloc() override;
bool addPostRegAlloc() override;
bool addPreSched2() override;
bool addPreEmitPass() override;
};
} // namespace
TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM) {
return new HexagonPassConfig(this, PM);
}
bool HexagonPassConfig::addInstSelector() {
HexagonTargetMachine &TM = getHexagonTargetMachine();
bool NoOpt = (getOptLevel() == CodeGenOpt::None);
if (!NoOpt)
addPass(createHexagonRemoveExtendArgs(TM));
addPass(createHexagonISelDag(TM, getOptLevel()));
if (!NoOpt) {
addPass(createHexagonPeephole());
printAndVerify("After hexagon peephole pass");
}
return false;
}
bool HexagonPassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None)
if (!DisableHardwareLoops)
addPass(createHexagonHardwareLoops());
return false;
}
bool HexagonPassConfig::addPostRegAlloc() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
if (getOptLevel() != CodeGenOpt::None)
if (!DisableHexagonCFGOpt)
addPass(createHexagonCFGOptimizer(TM));
return false;
}
bool HexagonPassConfig::addPreSched2() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
addPass(createHexagonCopyToCombine());
if (getOptLevel() != CodeGenOpt::None)
addPass(&IfConverterID);
addPass(createHexagonSplitConst32AndConst64(TM));
printAndVerify("After hexagon split const32/64 pass");
return true;
}
bool HexagonPassConfig::addPreEmitPass() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
bool NoOpt = (getOptLevel() == CodeGenOpt::None);
if (!NoOpt)
addPass(createHexagonNewValueJump());
// Expand Spill code for predicate registers.
addPass(createHexagonExpandPredSpillCode(TM));
// Split up TFRcondsets into conditional transfers.
addPass(createHexagonSplitTFRCondSets(TM));
// Create Packets.
if (!NoOpt) {
if (!DisableHardwareLoops)
addPass(createHexagonFixupHwLoops());
addPass(createHexagonPacketizer());
}
return false;
}
|