mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
1643bee451
In the ARM backend, for historical reasons we have only some targets using Machine Scheduling. The rest use the old list scheduler as they are using itinaries and the list scheduler seems to produce better code (and not crash running out of register on v6m codes). So whether to use the MIScheduler or not is checked at runtime from the subtarget features. This is fine, except for post-ra scheduling. Whether to use the old post-ra list scheduler or the post-ra machine schedule is decided as the pass manager is set up, in arms case from a newly constructed subtarget. Under some situations, like LTO, this won't include the correct cpu so can pick the wrong option. This can have a surprising effect on performance. To fix that, this patch overrides targetSchedulesPostRAScheduling and addPreSched2 in the ARM backend, adding _both_ post-ra schedulers and picking at runtime which to execute. To pick between the two I've had to add a enablePostRAMachineScheduler() method that normally returns enableMachineScheduler() && enablePostRAScheduler(), which can be overridden to enable just one of PostRAMachineScheduler vs PostRAScheduler. Thanks to David Penry for the identifying this problem. Differential Revision: https://reviews.llvm.org/D69775
100 lines
3.5 KiB
C++
100 lines
3.5 KiB
C++
//===-- ARMTargetMachine.h - Define TargetMachine for ARM -------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file declares the ARM specific subclass of TargetMachine.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
|
|
#define LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
|
|
|
|
#include "ARMSubtarget.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
#include "llvm/Support/CodeGen.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include <memory>
|
|
|
|
namespace llvm {
|
|
|
|
class ARMBaseTargetMachine : public LLVMTargetMachine {
|
|
public:
|
|
enum ARMABI {
|
|
ARM_ABI_UNKNOWN,
|
|
ARM_ABI_APCS,
|
|
ARM_ABI_AAPCS, // ARM EABI
|
|
ARM_ABI_AAPCS16
|
|
} TargetABI;
|
|
|
|
protected:
|
|
std::unique_ptr<TargetLoweringObjectFile> TLOF;
|
|
bool isLittle;
|
|
mutable StringMap<std::unique_ptr<ARMSubtarget>> SubtargetMap;
|
|
|
|
public:
|
|
ARMBaseTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
|
|
StringRef FS, const TargetOptions &Options,
|
|
Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
|
|
CodeGenOpt::Level OL, bool isLittle);
|
|
~ARMBaseTargetMachine() override;
|
|
|
|
const ARMSubtarget *getSubtargetImpl(const Function &F) const override;
|
|
// DO NOT IMPLEMENT: There is no such thing as a valid default subtarget,
|
|
// subtargets are per-function entities based on the target-specific
|
|
// attributes of each function.
|
|
const ARMSubtarget *getSubtargetImpl() const = delete;
|
|
bool isLittleEndian() const { return isLittle; }
|
|
|
|
TargetTransformInfo getTargetTransformInfo(const Function &F) override;
|
|
|
|
// Pass Pipeline Configuration
|
|
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
|
|
|
|
TargetLoweringObjectFile *getObjFileLowering() const override {
|
|
return TLOF.get();
|
|
}
|
|
|
|
bool isTargetHardFloat() const {
|
|
return TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
|
|
TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
|
|
TargetTriple.getEnvironment() == Triple::EABIHF ||
|
|
(TargetTriple.isOSBinFormatMachO() &&
|
|
TargetTriple.getSubArch() == Triple::ARMSubArch_v7em) ||
|
|
TargetTriple.isOSWindows() ||
|
|
TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16;
|
|
}
|
|
|
|
bool targetSchedulesPostRAScheduling() const override { return true; };
|
|
};
|
|
|
|
/// ARM/Thumb little endian target machine.
|
|
///
|
|
class ARMLETargetMachine : public ARMBaseTargetMachine {
|
|
public:
|
|
ARMLETargetMachine(const Target &T, const Triple &TT, StringRef CPU,
|
|
StringRef FS, const TargetOptions &Options,
|
|
Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
|
|
CodeGenOpt::Level OL, bool JIT);
|
|
};
|
|
|
|
/// ARM/Thumb big endian target machine.
|
|
///
|
|
class ARMBETargetMachine : public ARMBaseTargetMachine {
|
|
public:
|
|
ARMBETargetMachine(const Target &T, const Triple &TT, StringRef CPU,
|
|
StringRef FS, const TargetOptions &Options,
|
|
Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
|
|
CodeGenOpt::Level OL, bool JIT);
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
|