[clang] [llvm] [RISC-V] Add support for MIPS P8700 CPU (PR #117865)
Oren Benita Ben Simhon via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 3 08:25:25 PST 2024
================
@@ -0,0 +1,158 @@
+//===----------------------- RISCVRemoveBackToBackBranches.cpp ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "RISCVInstrInfo.h"
+#include "RISCVSubtarget.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-remove-back-to-back-branches"
+
+STATISTIC(NumInsertedAligments, "Number of aligments set");
+
+namespace {
+
+// According to the MIPS specification, there shouldn't be two conditional
+// branches in the same 8-byte aligned region of code.
+constexpr unsigned NumberOfBytesOfCodeRegion = 8;
+
+class RISCVRemoveBackToBackBranches : public MachineFunctionPass {
+public:
+ static char ID;
+
+ RISCVRemoveBackToBackBranches() : MachineFunctionPass(ID) {
+ initializeRISCVRemoveBackToBackBranchesPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ StringRef getPassName() const override {
+ return "RISCV Remove Back To Back Branches Pass";
+ }
+
+ bool runOnMachineFunction(MachineFunction &F) override;
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::NoVRegs);
+ }
+
+private:
+ const RISCVSubtarget *STI;
+ const RISCVInstrInfo *TII;
+};
+
+} // end of anonymous namespace
+
+char RISCVRemoveBackToBackBranches::ID = 0;
+
+INITIALIZE_PASS(RISCVRemoveBackToBackBranches, DEBUG_TYPE,
+ "Fix hazards by removing back to back branches", false, false)
+
+/// Returns a pass that clears pipeline hazards.
+FunctionPass *llvm::createRISCVRemoveBackToBackBranches() {
+ return new RISCVRemoveBackToBackBranches();
+}
+
+static bool CheckCompressedISA(MachineBasicBlock *MBB,
+ const RISCVInstrInfo *TII) {
+ unsigned SizeInBytes = 0;
+ for (auto &I : *MBB) {
+ // Skip some 0-sized meta instrucitons, such as debug ones.
+ if (!TII->getInstSizeInBytes(I))
+ continue;
+
+ SizeInBytes += TII->getInstSizeInBytes(I);
+
+ // This means that there is something other than the conditional branch
+ // here.
+ if (!I.isConditionalBranch())
+ continue;
+
+ // If it is a conditional branch, make sure it is the last one
+ // in this MBB and the cumulative size in bytes of other instructions in the
+ // block is <= 6 (since there potentially could be space for the two
+ // branches in the same 8-byte aligned code region, when compressed version
+ // of the instructions (16-bit size) is being used).
+ if (&I == &*MBB->getLastNonDebugInstr()) {
+ if (SizeInBytes <= 6)
+ return true;
+ return false;
+ }
+ }
+
+ return false;
+}
+
+static bool CheckNonCompressedISA(MachineBasicBlock *MBB,
+ const RISCVInstrInfo *TII) {
+ for (auto &I : *MBB) {
+ // Skip some 0-sized meta instrucitons, such as debug ones.
+ if (!TII->getInstSizeInBytes(I))
+ continue;
+
+ // This means that there is something other than the conditional branch
+ // here.
+ if (!I.isConditionalBranch())
+ return false;
+
+ // If it is a conditional branch, make sure it is the last one
+ // in this MBB.
+ if (&I == &*MBB->getLastNonDebugInstr())
+ return true;
+ return false;
+ }
+ return false;
+}
+
+bool RISCVRemoveBackToBackBranches::runOnMachineFunction(MachineFunction &MF) {
+ STI = &static_cast<const RISCVSubtarget &>(MF.getSubtarget());
+ TII = static_cast<const RISCVInstrInfo *>(STI->getInstrInfo());
+
+ if (!STI->shouldRemoveBackToBackBranches()) {
+ LLVM_DEBUG(llvm::dbgs()
+ << "Ignoring RISCV Remove Back To Back Branches Pass\n");
+ return false;
+ }
+
+ bool Changed = false;
+ for (auto &MBB : MF) {
+ auto BBTerminator = MBB.getFirstTerminator();
+ // If it is not a conditional branch, we are not interested.
+ if (BBTerminator == MBB.end() ||
+ &*BBTerminator != &*MBB.getLastNonDebugInstr() ||
+ !BBTerminator->isConditionalBranch())
+ continue;
+
+ for (auto &Successor : MBB.successors()) {
+ // Set up aligment in order to avoid hazards. No 2 conditional branches
+ // should be in the same 8-byte aligned region of code. Similar to MIPS
+ // forbidden slots problem. We may want to insert a NOP only, but we
+ // need to think of Compressed ISA, so it is more safe to just set up
+ // aligment to the successor block if it meets requirements.
+ bool ShouldSetAligment = STI->getFeatureBits()[RISCV::FeatureStdExtC]
+ ? CheckCompressedISA(Successor, TII)
+ : CheckNonCompressedISA(Successor, TII);
+ if (ShouldSetAligment) {
----------------
OrenBenSimhon wrote:
In case the successor of a BB is itself, you probably don't want to add alignment
https://github.com/llvm/llvm-project/pull/117865
More information about the cfe-commits
mailing list