ARMOptimizeBarriersPass.cpp [plain text]
#include "ARM.h"
#include "ARMInstrInfo.h"
#include "ARMMachineFunctionInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
using namespace llvm;
#define DEBUG_TYPE "double barriers"
STATISTIC(NumDMBsRemoved, "Number of DMBs removed");
namespace {
class ARMOptimizeBarriersPass : public MachineFunctionPass {
public:
static char ID;
ARMOptimizeBarriersPass() : MachineFunctionPass(ID) {}
bool runOnMachineFunction(MachineFunction &Fn) override;
const char *getPassName() const override {
return "optimise barriers pass";
}
private:
};
char ARMOptimizeBarriersPass::ID = 0;
}
static bool CanMovePastDMB(const MachineInstr *MI) {
return !(MI->mayLoad() ||
MI->mayStore() ||
MI->hasUnmodeledSideEffects() ||
MI->isCall() ||
MI->isReturn());
}
bool ARMOptimizeBarriersPass::runOnMachineFunction(MachineFunction &MF) {
std::vector<MachineInstr *> ToRemove;
int64_t DMBType = -1;
for (auto &MBB : MF) {
bool IsRemovableNextDMB = false;
for (auto &MI : MBB) {
if (MI.getOpcode() == ARM::DMB) {
if (IsRemovableNextDMB) {
if (MI.getOperand(0).getImm() == DMBType) {
ToRemove.push_back(&MI);
} else {
DMBType = MI.getOperand(0).getImm();
}
} else {
IsRemovableNextDMB = true;
DMBType = MI.getOperand(0).getImm();
}
} else if (!CanMovePastDMB(&MI)) {
IsRemovableNextDMB = false;
}
}
}
for (auto MI : ToRemove) {
MI->eraseFromParent();
++NumDMBsRemoved;
}
return NumDMBsRemoved > 0;
}
FunctionPass *llvm::createARMOptimizeBarriersPass() {
return new ARMOptimizeBarriersPass();
}