From 95d63ac8d734bb708403b6ae733a95723cc11ebb Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 2 Apr 2024 12:39:01 +0200 Subject: [PATCH 01/67] add function call test to check how stack cache is used --- .../single_source/stackcache/funccall.ll | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll new file mode 100644 index 000000000000..96b6d7f21c9c --- /dev/null +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll @@ -0,0 +1,27 @@ +; RUN: EXEC_ARGS="1=3 2=4"; \ +; RUN: WITH_DEBUG=true; \ +; RUN: %test_execution +; END. +;////////////////////////////////////////////////////////////////////////////////////////////////// +; +; Tests that multiplying by 2 is optimized into a shl instruction. +; +;////////////////////////////////////////////////////////////////////////////////////////////////// + +; CHECK-LABEL: inc: +define i32 @inc(i32 %a) { +entry: + %0 = add nsw i32 %a, 1 + ret i32 %0 +} + + +; CHECK-LABEL: main: +define i32 @main(i32 %value) { +entry: + %call = call i32 @inc(i32 %value) + %call1 = call i32 @inc(i32 %call) + + ret i32 %call1 +} + From 2cf09f0ceab5198f4f2b7fdaaf302636ab73040c Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 16 Apr 2024 12:59:07 +0200 Subject: [PATCH 02/67] fix comment --- .../programs/bounded/single_source/stackcache/funccall.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll index 96b6d7f21c9c..d9fb96b33c25 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll @@ -4,7 +4,7 @@ ; END. ;////////////////////////////////////////////////////////////////////////////////////////////////// ; -; Tests that multiplying by 2 is optimized into a shl instruction. +; Tests that incrementing twice using a function works. ; ;////////////////////////////////////////////////////////////////////////////////////////////////// From 0efb412bd02a4720642036e1b29e24622bbb5702 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 16 Apr 2024 12:59:15 +0200 Subject: [PATCH 03/67] add struct test --- .../single_source/stackcache/struct.ll | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll new file mode 100644 index 000000000000..3d010306e71c --- /dev/null +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll @@ -0,0 +1,40 @@ +;////////////////////////////////////////////////////////////////////////////////////////////////// +; +; Tests that summing two members of a struct is correct +; +;////////////////////////////////////////////////////////////////////////////////////////////////// + + +%struct.t = type { i32, i32 } + +@__const.main.a = private unnamed_addr constant %struct.t { i32 5, i32 5 }, align 4 + +; Function Attrs: noinline nounwind optnone +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %a = alloca %struct.t, align 4 + %x = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + %0 = bitcast %struct.t* %a to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast (%struct.t* @__const.main.a to i8*), i32 8, i1 false) + store i32 0, i32* %x, align 4 + %a1 = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 0 + %1 = load i32, i32* %a1, align 4 + %2 = load i32, i32* %x, align 4 + %add = add nsw i32 %2, %1 + store i32 %add, i32* %x, align 4 + %b = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 1 + %3 = load i32, i32* %b, align 4 + %4 = load i32, i32* %x, align 4 + %add2 = add nsw i32 %4, %3 + store i32 %add2, i32* %x, align 4 + %5 = load i32, i32* %x, align 4 + ret i32 %5 +} + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #1 + +attributes #0 = { noinline nounwind optnone "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nofree nosync nounwind willreturn } \ No newline at end of file From 314cafd8ad7c13d1f8d7af0d20a28a939dbe1344 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 16 Apr 2024 14:39:45 +0200 Subject: [PATCH 04/67] identify point of interest for stack cache optimization --- llvm/lib/Target/Patmos/PatmosFrameLowering.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp index bf5b605f6293..2e140e2abc83 100644 --- a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp +++ b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp @@ -331,6 +331,10 @@ void PatmosFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &M } } + /*PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); + BitVector SCFI = PMFI.getStackCacheFIs(); + PMFI.setStackCacheFIs(SCFI.set());*/ + // TODO Allocate objects on stack cache instead of shadow stack } void PatmosFrameLowering::emitEpilogue(MachineFunction &MF, From 29d4f331f2d8ee42af209b9957c70da166ed376b Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 16 Apr 2024 23:58:24 +0200 Subject: [PATCH 05/67] add PatmosStackCachePromotion pass --- llvm/lib/Target/Patmos/CMakeLists.txt | 1 + llvm/lib/Target/Patmos/Patmos.h | 1 + .../lib/Target/Patmos/PatmosFrameLowering.cpp | 5 -- .../Patmos/PatmosStackCachePromotion.cpp | 44 +++++++++++++++ .../Target/Patmos/PatmosStackCachePromotion.h | 55 +++++++++++++++++++ .../lib/Target/Patmos/PatmosTargetMachine.cpp | 2 + .../single_source/stackcache/funccall.ll | 22 ++++++-- .../single_source/stackcache/struct.ll | 43 ++++++++++----- 8 files changed, 150 insertions(+), 23 deletions(-) create mode 100644 llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp create mode 100644 llvm/lib/Target/Patmos/PatmosStackCachePromotion.h diff --git a/llvm/lib/Target/Patmos/CMakeLists.txt b/llvm/lib/Target/Patmos/CMakeLists.txt index 55f857480e33..b3e7b9e85f9f 100644 --- a/llvm/lib/Target/Patmos/CMakeLists.txt +++ b/llvm/lib/Target/Patmos/CMakeLists.txt @@ -26,6 +26,7 @@ add_llvm_target(PatmosCodeGen PatmosSelectionDAGInfo.cpp PatmosAsmPrinter.cpp PatmosMCInstLower.cpp + PatmosStackCachePromotion.cpp PatmosDelaySlotFiller.cpp PatmosFunctionSplitter.cpp PatmosDelaySlotKiller.cpp diff --git a/llvm/lib/Target/Patmos/Patmos.h b/llvm/lib/Target/Patmos/Patmos.h index 1d8c90d9cb24..b8468dd9819e 100644 --- a/llvm/lib/Target/Patmos/Patmos.h +++ b/llvm/lib/Target/Patmos/Patmos.h @@ -41,6 +41,7 @@ namespace llvm { FunctionPass *createPatmosSPBundlingPass(const PatmosTargetMachine &tm); FunctionPass *createOppositePredicateCompensationPass(const PatmosTargetMachine &tm); FunctionPass *createDataCacheAccessEliminationPass(const PatmosTargetMachine &tm); + FunctionPass *createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm); FunctionPass *createMemoryAccessNormalizationPass(const PatmosTargetMachine &tm); FunctionPass *createPatmosSPReducePass(const PatmosTargetMachine &tm); FunctionPass *createPreRegallocReduce(const PatmosTargetMachine &tm); diff --git a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp index 2e140e2abc83..4c012d9363d6 100644 --- a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp +++ b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp @@ -330,11 +330,6 @@ void PatmosFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &M MI->setFlag(MachineInstr::FrameSetup); } } - - /*PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); - BitVector SCFI = PMFI.getStackCacheFIs(); - PMFI.setStackCacheFIs(SCFI.set());*/ - // TODO Allocate objects on stack cache instead of shadow stack } void PatmosFrameLowering::emitEpilogue(MachineFunction &MF, diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp new file mode 100644 index 000000000000..88b9ade4acf9 --- /dev/null +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -0,0 +1,44 @@ +//===-- PatmosStackCachePromotion.cpp - Remove unused function declarations ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "PatmosStackCachePromotion.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" + +using namespace llvm; + +STATISTIC(LoadsConverted, "Number of data-cache loads converted to stack cache loads"); +STATISTIC(SavesConverted, "Number of data-cache saves converted to stack cache saves"); + +static cl::opt EnableStackCachePromotion("mpatmos-enable-stack-cache-promotion", + cl::init(false), + cl::desc("Enable the compiler to promot data to the stack cache")); + +char PatmosStackCachePromotion::ID = 0; + +/// createDataCacheAccessEliminationPass - Returns a new DataCacheAccessElimination +/// \see DataCacheAccessElimination +FunctionPass *llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { + return new PatmosStackCachePromotion(tm); +} + +bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { + if (EnableStackCachePromotion) { + LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); + + // TODO Promote some data to stack cache + } else { + LLVM_DEBUG(dbgs() << "Disabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); + } + return true; +} + + diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h new file mode 100644 index 000000000000..37c27877ec4c --- /dev/null +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -0,0 +1,55 @@ +//===-- PatmosStackCachePromotion.h - Promote values ti the stack-cache. -=====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// +#ifndef PATMOSSTACKCACHEPROMOTION +#define PATMOSSTACKCACHEPROMOTION + +#include "Patmos.h" +#include "PatmosTargetMachine.h" +#include "PatmosRegisterInfo.h" + + +#include +#include + +#define DEBUG_TYPE "patmos-stack-cache-promotion" + +namespace llvm { + +class PatmosStackCachePromotion : public MachineFunctionPass { + +private: + + const PatmosTargetMachine &TM; + const PatmosSubtarget &STC; + const PatmosInstrInfo *TII; + const PatmosRegisterInfo *TRI; + +public: + static char ID; + PatmosStackCachePromotion(const PatmosTargetMachine &tm): + MachineFunctionPass(ID), TM(tm), + STC(*tm.getSubtargetImpl()), + TII(static_cast(tm.getInstrInfo())), + TRI(static_cast(tm.getRegisterInfo())) + {} + + /// getPassName - Return the pass' name. + StringRef getPassName() const override { + return "Patmos StackCache-Promotion pass (machine code)"; + } + + bool runOnMachineFunction(MachineFunction &MF) override ; + +}; + +} // End llvm namespace + +#endif diff --git a/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp b/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp index df310c18d39b..b6de6875ffa3 100644 --- a/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp +++ b/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp @@ -177,6 +177,8 @@ namespace { /// This method may be implemented by targets that want to run passes after /// register allocation pass pipeline but before prolog-epilog insertion. void addPostRegAlloc() override { + addPass(createPatmosStackCachePromotionPass(getPatmosTargetMachine())); + if(PatmosSinglePathInfo::isEnabled() && PatmosSinglePathInfo::useNewSinglePathTransform()) { // The previous register allocation allocated the predicate registers too. // We returns those predicate registers to virtual registers so that they diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll index d9fb96b33c25..a27210f82678 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/funccall.ll @@ -1,4 +1,4 @@ -; RUN: EXEC_ARGS="1=3 2=4"; \ +; RUN: EXEC_ARGS="1=2 2=3"; \ ; RUN: WITH_DEBUG=true; \ ; RUN: %test_execution ; END. @@ -8,20 +8,32 @@ ; ;////////////////////////////////////////////////////////////////////////////////////////////////// -; CHECK-LABEL: inc: define i32 @inc(i32 %a) { entry: %0 = add nsw i32 %a, 1 ret i32 %0 } +define i32 @inc1(i32 %a) { +entry: + %0 = call i32 @inc(i32 %a) + + ret i32 %0 +} + +define i32 @inc2(i32 %a) { +entry: + %0 = call i32 @inc1(i32 %a); + + ret i32 %0 +} + ; CHECK-LABEL: main: define i32 @main(i32 %value) { entry: - %call = call i32 @inc(i32 %value) - %call1 = call i32 @inc(i32 %call) + %call = call i32 @inc2(i32 %value) - ret i32 %call1 + ret i32 %call } diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll index 3d010306e71c..768538a59235 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/struct.ll @@ -1,3 +1,6 @@ +; RUN: EXEC_ARGS="1=7 2=8"; \ +; RUN: %test_execution +; END. ;////////////////////////////////////////////////////////////////////////////////////////////////// ; ; Tests that summing two members of a struct is correct @@ -10,27 +13,41 @@ @__const.main.a = private unnamed_addr constant %struct.t { i32 5, i32 5 }, align 4 ; Function Attrs: noinline nounwind optnone -define dso_local i32 @main() #0 { +define dso_local i32 @main(i32 %value) #0 { entry: - %retval = alloca i32, align 4 + ; 0 = (struct.t) malloc(sizeof(struct.t)); %a = alloca %struct.t, align 4 + + ; x = (int) malloc(4); %x = alloca i32, align 4 - store i32 0, i32* %retval, align 4 - %0 = bitcast %struct.t* %a to i8* - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast (%struct.t* @__const.main.a to i8*), i32 8, i1 false) + + + %tmpa = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 0 + store i32 %value, i32* %tmpa, align 4 + + %tmpb = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 1 + store i32 6, i32* %tmpb, align 4 + + ; x = 0; store i32 0, i32* %x, align 4 + + ; x += a; %a1 = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 0 - %1 = load i32, i32* %a1, align 4 - %2 = load i32, i32* %x, align 4 - %add = add nsw i32 %2, %1 + %0 = load i32, i32* %a1, align 4 + %1 = load i32, i32* %x, align 4 + %add = add nsw i32 %1, %0 + + ; x += b; store i32 %add, i32* %x, align 4 %b = getelementptr inbounds %struct.t, %struct.t* %a, i32 0, i32 1 - %3 = load i32, i32* %b, align 4 - %4 = load i32, i32* %x, align 4 - %add2 = add nsw i32 %4, %3 + %2 = load i32, i32* %b, align 4 + %3 = load i32, i32* %x, align 4 + %add2 = add nsw i32 %3, %2 store i32 %add2, i32* %x, align 4 - %5 = load i32, i32* %x, align 4 - ret i32 %5 + + ; return x; + %4 = load i32, i32* %x, align 4 + ret i32 %4 } ; Function Attrs: argmemonly nofree nosync nounwind willreturn From 752be0ef1a75352f57d6dff5433c96d00f644cd0 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 00:50:55 +0200 Subject: [PATCH 06/67] add res and free to PatmosStackCachePromotion pass --- .../Patmos/PatmosStackCachePromotion.cpp | 147 ++++++++++++++++-- 1 file changed, 134 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 88b9ade4acf9..7476d21c29b8 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -1,4 +1,5 @@ -//===-- PatmosStackCachePromotion.cpp - Remove unused function declarations ------------===// +//===-- PatmosStackCachePromotion.cpp - Remove unused function declarations +//------------===// // // The LLVM Compiler Infrastructure // @@ -15,30 +16,150 @@ using namespace llvm; -STATISTIC(LoadsConverted, "Number of data-cache loads converted to stack cache loads"); -STATISTIC(SavesConverted, "Number of data-cache saves converted to stack cache saves"); +STATISTIC(LoadsConverted, + "Number of data-cache loads converted to stack cache loads"); +STATISTIC(SavesConverted, + "Number of data-cache saves converted to stack cache saves"); -static cl::opt EnableStackCachePromotion("mpatmos-enable-stack-cache-promotion", - cl::init(false), - cl::desc("Enable the compiler to promot data to the stack cache")); +STATISTIC(BytesToStackCache, + "Number of data-cache loads converted to stack cache loads"); + +static cl::opt EnableStackCachePromotion( + "mpatmos-enable-stack-cache-promotion", cl::init(false), + cl::desc("Enable the compiler to promot data to the stack cache")); char PatmosStackCachePromotion::ID = 0; -/// createDataCacheAccessEliminationPass - Returns a new DataCacheAccessElimination -/// \see DataCacheAccessElimination -FunctionPass *llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { +/// createDataCacheAccessEliminationPass - Returns a new +/// DataCacheAccessElimination \see DataCacheAccessElimination +FunctionPass * +llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (EnableStackCachePromotion) { - LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); + LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " + << MF.getFunction().getName() << "\n"); // TODO Promote some data to stack cache + for (auto BB_iter = MF.begin(), BB_iter_end = MF.end(); + BB_iter != BB_iter_end; ++BB_iter) { + for (auto instr_iter = BB_iter->begin(), instr_iter_end = BB_iter->end(); + instr_iter != instr_iter_end; ++instr_iter) { + switch (instr_iter->getOpcode()) { + case Patmos::LWC: + case Patmos::LHC: + case Patmos::LBC: + case Patmos::LHUC: + case Patmos::LBUC: + LoadsConverted++; + break; + case Patmos::SWC: + BytesToStackCache += 4; + SavesConverted++; + break; + case Patmos::SHC: + BytesToStackCache += 2; + SavesConverted++; + break; + case Patmos::SBC: + BytesToStackCache += 1; + SavesConverted++; + break; + default: + // Not a data cache accesses, ignore + continue; + } + } + } + + LLVM_DEBUG(dbgs() << "Converting: " << LoadsConverted << " Loads and " + << SavesConverted << " Saves resulting in " << BytesToStackCache << " Bytes to SC\n"); + + auto startofblock = MF.begin(); + auto startInstr = startofblock->begin(); + + auto *ensureInstr = MF.CreateMachineInstr(TII->get(Patmos::SRESi), + startInstr->getDebugLoc()); + MachineInstrBuilder ensureInstrBuilder(MF, ensureInstr); + AddDefaultPred(ensureInstrBuilder); + ensureInstrBuilder.addImm(BytesToStackCache); + + startofblock->insert(startInstr, ensureInstr); + + for (auto BB_iter = MF.begin(), BB_iter_end = MF.end(); + BB_iter != BB_iter_end; ++BB_iter) { + for (auto instr_iter = BB_iter->begin(), instr_iter_end = BB_iter->end(); + instr_iter != instr_iter_end; ++instr_iter) { + unsigned convert_to; + switch (instr_iter->getOpcode()) { + case Patmos::LWC: + LoadsConverted++; + convert_to = Patmos::LWS; + break; + case Patmos::LHC: + LoadsConverted++; + convert_to = Patmos::LHS; + break; + case Patmos::LBC: + LoadsConverted++; + convert_to = Patmos::LBS; + break; + case Patmos::LHUC: + LoadsConverted++; + convert_to = Patmos::LHUS; + break; + case Patmos::LBUC: + LoadsConverted++; + convert_to = Patmos::LBUM; + break; + case Patmos::SWC: + SavesConverted++; + convert_to = Patmos::SWS; + break; + case Patmos::SHC: + SavesConverted++; + convert_to = Patmos::SHS; + break; + case Patmos::SBC: + SavesConverted++; + convert_to = Patmos::SBS; + break; + default: + // Not a data cache accesses, ignore + continue; + } + + // Create new instruction accessing main memory instead + /*auto *new_instr = MF.CreateMachineInstr(TII->get(convert_to), + instr_iter->getDebugLoc()); + MachineInstrBuilder new_instr_builder(MF, new_instr); + + // Give it the same operands + for (auto op : instr_iter->operands()) { + new_instr_builder.add(op); + } + + // Replace old instruction by new one in BB + BB_iter->insertAfter(instr_iter, new_instr); + instr_iter = BB_iter->erase(&*instr_iter);*/ + } + } + + auto& endofBlock = MF.back(); + auto& endInstr = endofBlock.back(); + + auto *freeInstr = MF.CreateMachineInstr(TII->get(Patmos::SFREEi), + endInstr.getDebugLoc()); + MachineInstrBuilder freeInstrBuilder(MF, freeInstr); + AddDefaultPred(freeInstrBuilder); + freeInstrBuilder.addImm(BytesToStackCache); + + endofBlock.insert(endInstr, freeInstr); } else { - LLVM_DEBUG(dbgs() << "Disabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); + LLVM_DEBUG(dbgs() << "Disabled Stack Cache promotion for: " + << MF.getFunction().getName() << "\n"); } return true; } - - From edb0afc4a80620d6bd838b1d897584c3874bb64e Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 11:56:34 +0200 Subject: [PATCH 07/67] add stack cache alloc/dealloc --- .../Patmos/PatmosStackCachePromotion.cpp | 118 +++--------------- 1 file changed, 16 insertions(+), 102 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 7476d21c29b8..d090450715a1 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -13,6 +13,7 @@ #include "PatmosStackCachePromotion.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFrameInfo.h" using namespace llvm; @@ -21,9 +22,6 @@ STATISTIC(LoadsConverted, STATISTIC(SavesConverted, "Number of data-cache saves converted to stack cache saves"); -STATISTIC(BytesToStackCache, - "Number of data-cache loads converted to stack cache loads"); - static cl::opt EnableStackCachePromotion( "mpatmos-enable-stack-cache-promotion", cl::init(false), cl::desc("Enable the compiler to promot data to the stack cache")); @@ -42,41 +40,16 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - // TODO Promote some data to stack cache - for (auto BB_iter = MF.begin(), BB_iter_end = MF.end(); - BB_iter != BB_iter_end; ++BB_iter) { - for (auto instr_iter = BB_iter->begin(), instr_iter_end = BB_iter->end(); - instr_iter != instr_iter_end; ++instr_iter) { - switch (instr_iter->getOpcode()) { - case Patmos::LWC: - case Patmos::LHC: - case Patmos::LBC: - case Patmos::LHUC: - case Patmos::LBUC: - LoadsConverted++; - break; - case Patmos::SWC: - BytesToStackCache += 4; - SavesConverted++; - break; - case Patmos::SHC: - BytesToStackCache += 2; - SavesConverted++; - break; - case Patmos::SBC: - BytesToStackCache += 1; - SavesConverted++; - break; - default: - // Not a data cache accesses, ignore - continue; - } - } + // Calculate the amount of bytes to store on SC + MachineFrameInfo &MFI = MF.getFrameInfo(); + unsigned stackSize = 0; + for(unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { + stackSize += MFI.getObjectSize(FI); } - LLVM_DEBUG(dbgs() << "Converting: " << LoadsConverted << " Loads and " - << SavesConverted << " Saves resulting in " << BytesToStackCache << " Bytes to SC\n"); + LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << "MFIs resulting in " << stackSize << " bytes to SC\n"); + // Insert Reserve before function start auto startofblock = MF.begin(); auto startInstr = startofblock->begin(); @@ -84,82 +57,23 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { startInstr->getDebugLoc()); MachineInstrBuilder ensureInstrBuilder(MF, ensureInstr); AddDefaultPred(ensureInstrBuilder); - ensureInstrBuilder.addImm(BytesToStackCache); + ensureInstrBuilder.addImm(stackSize); startofblock->insert(startInstr, ensureInstr); - for (auto BB_iter = MF.begin(), BB_iter_end = MF.end(); - BB_iter != BB_iter_end; ++BB_iter) { - for (auto instr_iter = BB_iter->begin(), instr_iter_end = BB_iter->end(); - instr_iter != instr_iter_end; ++instr_iter) { - unsigned convert_to; - switch (instr_iter->getOpcode()) { - case Patmos::LWC: - LoadsConverted++; - convert_to = Patmos::LWS; - break; - case Patmos::LHC: - LoadsConverted++; - convert_to = Patmos::LHS; - break; - case Patmos::LBC: - LoadsConverted++; - convert_to = Patmos::LBS; - break; - case Patmos::LHUC: - LoadsConverted++; - convert_to = Patmos::LHUS; - break; - case Patmos::LBUC: - LoadsConverted++; - convert_to = Patmos::LBUM; - break; - case Patmos::SWC: - SavesConverted++; - convert_to = Patmos::SWS; - break; - case Patmos::SHC: - SavesConverted++; - convert_to = Patmos::SHS; - break; - case Patmos::SBC: - SavesConverted++; - convert_to = Patmos::SBS; - break; - default: - // Not a data cache accesses, ignore - continue; - } - - // Create new instruction accessing main memory instead - /*auto *new_instr = MF.CreateMachineInstr(TII->get(convert_to), - instr_iter->getDebugLoc()); - MachineInstrBuilder new_instr_builder(MF, new_instr); - - // Give it the same operands - for (auto op : instr_iter->operands()) { - new_instr_builder.add(op); - } - - // Replace old instruction by new one in BB - BB_iter->insertAfter(instr_iter, new_instr); - instr_iter = BB_iter->erase(&*instr_iter);*/ - } - } + // TODO Convert access to SC access - auto& endofBlock = MF.back(); - auto& endInstr = endofBlock.back(); + // Insert Free after function End + auto endofBlock = MF.rbegin(); + auto endInstr = endofBlock->rbegin(); auto *freeInstr = MF.CreateMachineInstr(TII->get(Patmos::SFREEi), - endInstr.getDebugLoc()); + endInstr->getDebugLoc()); MachineInstrBuilder freeInstrBuilder(MF, freeInstr); AddDefaultPred(freeInstrBuilder); - freeInstrBuilder.addImm(BytesToStackCache); + freeInstrBuilder.addImm(stackSize); - endofBlock.insert(endInstr, freeInstr); - } else { - LLVM_DEBUG(dbgs() << "Disabled Stack Cache promotion for: " - << MF.getFunction().getName() << "\n"); + endofBlock->insert(endInstr->getIterator(), freeInstr); } return true; } From e5fadf509234537ceb534fd039be8e95c3b2bbbe Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 12:16:53 +0200 Subject: [PATCH 08/67] add debug logs to PatmosStackCachePromotion pass --- .../Patmos/PatmosStackCachePromotion.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index d090450715a1..fbcb6c05c72c 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -11,9 +11,10 @@ //===----------------------------------------------------------------------===// #include "PatmosStackCachePromotion.h" +#include "TargetInfo/PatmosTargetInfo.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" using namespace llvm; @@ -42,12 +43,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { // Calculate the amount of bytes to store on SC MachineFrameInfo &MFI = MF.getFrameInfo(); - unsigned stackSize = 0; - for(unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - stackSize += MFI.getObjectSize(FI); - } + unsigned stackSize = MFI.estimateStackSize(MF); - LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << "MFIs resulting in " << stackSize << " bytes to SC\n"); + LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << " MFIs resulting in " << stackSize << " bytes to SC\n"); // Insert Reserve before function start auto startofblock = MF.begin(); @@ -61,6 +59,15 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { startofblock->insert(startInstr, ensureInstr); + + for(auto BB_iter = startofblock, BB_iter_end = MF.end(); BB_iter != BB_iter_end; ++BB_iter) { + for (auto instr_iter = startInstr, instr_iter_end = BB_iter->end(); + instr_iter != instr_iter_end; ++instr_iter) { + if (llvm::isMainMemLoadInst(instr_iter->getOpcode()) || llvm::isMainMemStoreInst(instr_iter->getOpcode())) { + LLVM_DEBUG(dbgs() << "Instr " << TII->getName(instr_iter->getOpcode()) << " with operands " << instr_iter->getNumOperands() << "\n"); + } + } + } // TODO Convert access to SC access // Insert Free after function End From 0331f6005a349632b341eb2cc50b1feb56c468b7 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 17:29:16 +0200 Subject: [PATCH 09/67] add debug logs to PatmosStackCachePromotion pass --- .../Patmos/PatmosStackCachePromotion.cpp | 65 +++++++++++++++++-- .../Target/Patmos/PatmosStackCachePromotion.h | 1 + 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index fbcb6c05c72c..cc96c563d486 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -36,6 +36,58 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } +void PatmosStackCachePromotion::processMachineInstruction( + MachineBasicBlock::iterator II) { + // TODO Convert access to SC access + + MachineInstr &MI = *II; + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + Register dataReg; + uint64_t basePtrReg; + uint64_t unknown1; + uint64_t offset; + uint64_t FrameDisplacement; + + if (llvm::isMainMemLoadInst(MI.getOpcode())) { + basePtrReg = MI.getOperand(1).getReg(); + dataReg = MI.getOperand(0).getReg(); + offset = MFI.getObjectOffset(MI.getOperand(3).getIndex()); + FrameDisplacement = MI.getOperand(4).getImm(); + unknown1 = MI.getOperand(2).getImm(); + + auto dataRegName = TII->getRegisterInfo().getRegAsmName(dataReg); + auto basePtrRegName = + basePtrReg > 0 ? TII->getRegisterInfo().getRegAsmName(basePtrReg) : "?"; + + LLVM_DEBUG(dbgs() << TII->getName(MI.getOpcode()) << " " << dataRegName + << " = " + << "[" << basePtrRegName << " + " << offset << "]" + << "\n"); + + } else if (llvm::isMainMemStoreInst(MI.getOpcode())) { + basePtrReg = MI.getOperand(0) + .getReg(); // This is not known yet at this point in time + dataReg = MI.getOperand(4).getReg(); + offset = MFI.getObjectOffset( + MI.getOperand(2) + .getIndex()); // This is not final yet at this point in time + FrameDisplacement = MI.getOperand(3).getImm(); // Always has to be zero + unknown1 = MI.getOperand(1).getImm(); + + auto dataRegName = TII->getRegisterInfo().getRegAsmName(dataReg); + auto basePtrRegName = + basePtrReg > 0 ? TII->getRegisterInfo().getRegAsmName(basePtrReg) : "?"; + + LLVM_DEBUG(dbgs() << TII->getName(MI.getOpcode()) << "[" << basePtrRegName + << " + " << offset << "] = " << dataRegName << "\n"); + } else { + return; + } +} + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " @@ -45,7 +97,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo &MFI = MF.getFrameInfo(); unsigned stackSize = MFI.estimateStackSize(MF); - LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << " MFIs resulting in " << stackSize << " bytes to SC\n"); + LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() + << " MFIs resulting in " << stackSize + << " bytes to SC\n"); // Insert Reserve before function start auto startofblock = MF.begin(); @@ -59,16 +113,13 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { startofblock->insert(startInstr, ensureInstr); - - for(auto BB_iter = startofblock, BB_iter_end = MF.end(); BB_iter != BB_iter_end; ++BB_iter) { + for (auto BB_iter = startofblock, BB_iter_end = MF.end(); + BB_iter != BB_iter_end; ++BB_iter) { for (auto instr_iter = startInstr, instr_iter_end = BB_iter->end(); instr_iter != instr_iter_end; ++instr_iter) { - if (llvm::isMainMemLoadInst(instr_iter->getOpcode()) || llvm::isMainMemStoreInst(instr_iter->getOpcode())) { - LLVM_DEBUG(dbgs() << "Instr " << TII->getName(instr_iter->getOpcode()) << " with operands " << instr_iter->getNumOperands() << "\n"); - } + processMachineInstruction(instr_iter); } } - // TODO Convert access to SC access // Insert Free after function End auto endofBlock = MF.rbegin(); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 37c27877ec4c..2004a56807ae 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -46,6 +46,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return "Patmos StackCache-Promotion pass (machine code)"; } + void processMachineInstruction(MachineBasicBlock::iterator II); bool runOnMachineFunction(MachineFunction &MF) override ; }; From 215917190f6e054a8a7a8d64a6c098042a0689b5 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 17:48:15 +0200 Subject: [PATCH 10/67] add instruction replacement to stack cache promotion pass --- .../Patmos/PatmosStackCachePromotion.cpp | 113 ++++++++++++++++++ .../Target/Patmos/PatmosStackCachePromotion.h | 1 + 2 files changed, 114 insertions(+) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index cc96c563d486..946df0e357f2 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -45,6 +45,87 @@ void PatmosStackCachePromotion::processMachineInstruction( MachineFunction &MF = *MBB.getParent(); const MachineFrameInfo &MFI = MF.getFrameInfo(); + unsigned FIOperandNum; + + if (llvm::isMainMemLoadInst(MI.getOpcode())) { + FIOperandNum = 3; + } else if (llvm::isMainMemStoreInst(MI.getOpcode())) { + FIOperandNum = 2; + } else { + return; + } + + int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); + int FrameOffset = MFI.getObjectOffset(FrameIndex); // TODO This has to be computed somewhere before + int FrameDisplacement = MI.getOperand(FIOperandNum+1).getImm(); + + int Offset = FrameOffset; + + unsigned opcode = MI.getOpcode(); + + // ensure that the offset fits the instruction + switch (opcode) + { + case Patmos::LWC: case Patmos::LWM: + case Patmos::SWC: case Patmos::SWM: + case Patmos::PSEUDO_PREG_SPILL: + case Patmos::PSEUDO_PREG_RELOAD: + // 9 bit + assert((Offset & 0x3) == 0); + Offset = (Offset >> 2) + FrameDisplacement; + break; + case Patmos::LHC: case Patmos::LHM: + case Patmos::LHUC: case Patmos::LHUM: + case Patmos::SHC: case Patmos::SHM: + // 8 bit + assert((Offset & 0x1) == 0); + Offset = (Offset >> 1) + FrameDisplacement; + + break; + case Patmos::LBC: case Patmos::LBM: + case Patmos::LBUC: case Patmos::LBUM: + case Patmos::SBC: case Patmos::SBM: + // 7 bit + Offset += FrameDisplacement; + break; + case Patmos::ADDi: + // 12 bit + Offset += FrameDisplacement; + break; + case Patmos::ADDl: + case Patmos::DBG_VALUE: + // all should be fine + Offset += FrameDisplacement; + break; + default: + llvm_unreachable("Unexpected operation with FrameIndex encountered."); + } + + switch (opcode) + { + case Patmos::LWC: case Patmos::LWM: opcode = Patmos::LWS; break; + case Patmos::LHC: case Patmos::LHM: opcode = Patmos::LHS; break; + case Patmos::LHUC: case Patmos::LHUM: opcode = Patmos::LHUS; break; + case Patmos::LBC: case Patmos::LBM: opcode = Patmos::LBS; break; + case Patmos::LBUC: case Patmos::LBUM: opcode = Patmos::LBUS; break; + case Patmos::SWC: case Patmos::SWM: opcode = Patmos::SWS; break; + case Patmos::SHC: case Patmos::SHM: opcode = Patmos::SHS; break; + case Patmos::SBC: case Patmos::SBM: opcode = Patmos::SBS; break; + case Patmos::ADDi: case Patmos::ADDl: case Patmos::DBG_VALUE: + break; + default: + llvm_unreachable("Unexpected operation with FrameIndex encountered."); + } + + // Update Data Cache instr to use Stack Cache + const MCInstrDesc &newMCID = TII->get(opcode); + MI.setDesc(newMCID); + + MI.getOperand(FIOperandNum).ChangeToRegister(Patmos::R0, false, false, false); + MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); + + /* + Register dataReg; uint64_t basePtrReg; uint64_t unknown1; @@ -85,6 +166,36 @@ void PatmosStackCachePromotion::processMachineInstruction( << " + " << offset << "] = " << dataRegName << "\n"); } else { return; + }*/ +} + +void PatmosStackCachePromotion::calcOffsets(MachineFunction& MF) { + MachineFrameInfo &MFI = MF.getFrameInfo(); + + SmallVector ObjectsToAllocate; + + for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { + if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) + continue; + if (MFI.isDeadObjectIndex(i)) + continue; + + ObjectsToAllocate.push_back(i); + } + + + int64_t offset = 0; + Align maxalign = MFI.getMaxAlign(); + for (auto &FrameIdx : ObjectsToAllocate) { + // AdjustStackOffset + Align Alignment = MFI.getObjectAlign(FrameIdx); + + maxalign = std::max(maxalign, Alignment); + offset = alignTo(offset, Alignment); + + MFI.setObjectOffset(FrameIdx, offset); + offset += MFI.getObjectSize(FrameIdx); + } } @@ -113,6 +224,8 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { startofblock->insert(startInstr, ensureInstr); + calcOffsets(MF); + for (auto BB_iter = startofblock, BB_iter_end = MF.end(); BB_iter != BB_iter_end; ++BB_iter) { for (auto instr_iter = startInstr, instr_iter_end = BB_iter->end(); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 2004a56807ae..57d21a359336 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -47,6 +47,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { } void processMachineInstruction(MachineBasicBlock::iterator II); + void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; }; From c9c64390c83307973ce892ae9dbe77da030d0960 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 21:00:59 +0200 Subject: [PATCH 11/67] fix PatmosStackCachePromotion pass erros --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 946df0e357f2..4f66656fabed 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -40,23 +40,24 @@ void PatmosStackCachePromotion::processMachineInstruction( MachineBasicBlock::iterator II) { // TODO Convert access to SC access + if (!II.isValid() || (II.getInstrIterator().getNodePtr()->isKnownSentinel())) return; // TODO Check why this is needed MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MBB.getParent(); const MachineFrameInfo &MFI = MF.getFrameInfo(); - unsigned FIOperandNum; - if (llvm::isMainMemLoadInst(MI.getOpcode())) { + unsigned FIOperandNum; + int FrameIndex; + if (TII->isLoadFromStackSlot(MI, FrameIndex)) { // For some reason the FrameDisplacement operand [4] sometimes is not 0 here? FIOperandNum = 3; - } else if (llvm::isMainMemStoreInst(MI.getOpcode())) { + } else if (TII->isStoreToStackSlot(MI, FrameIndex)) { // For some reason the FrameDisplacement operand [3] sometimes is not 0 here? FIOperandNum = 2; } else { return; } - int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); - int FrameOffset = MFI.getObjectOffset(FrameIndex); // TODO This has to be computed somewhere before + int FrameOffset = MFI.getObjectOffset(FrameIndex); int FrameDisplacement = MI.getOperand(FIOperandNum+1).getImm(); int Offset = FrameOffset; From 8155fafd0283e56e6cf81ec441e840b166a1a159 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 17 Apr 2024 21:06:51 +0200 Subject: [PATCH 12/67] fix PatmosStackCachePromotion pass erros --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 4f66656fabed..94d2cae0ca70 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -40,7 +40,6 @@ void PatmosStackCachePromotion::processMachineInstruction( MachineBasicBlock::iterator II) { // TODO Convert access to SC access - if (!II.isValid() || (II.getInstrIterator().getNodePtr()->isKnownSentinel())) return; // TODO Check why this is needed MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MBB.getParent(); @@ -231,6 +230,7 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { BB_iter != BB_iter_end; ++BB_iter) { for (auto instr_iter = startInstr, instr_iter_end = BB_iter->end(); instr_iter != instr_iter_end; ++instr_iter) { + if (!instr_iter.isValid() || (instr_iter.getInstrIterator().getNodePtr()->isKnownSentinel())) break; // TODO Check why this is needed processMachineInstruction(instr_iter); } } From dbb925421e42587f8f46f6226a496fe9a22d6335 Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Thu, 18 Apr 2024 17:21:54 +0200 Subject: [PATCH 13/67] prevent useless stack operations from beeing emitted --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 94d2cae0ca70..41631338ccbf 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -25,7 +25,7 @@ STATISTIC(SavesConverted, static cl::opt EnableStackCachePromotion( "mpatmos-enable-stack-cache-promotion", cl::init(false), - cl::desc("Enable the compiler to promot data to the stack cache")); + cl::desc("Enable the compiler to promote data to the stack cache")); char PatmosStackCachePromotion::ID = 0; @@ -208,6 +208,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo &MFI = MF.getFrameInfo(); unsigned stackSize = MFI.estimateStackSize(MF); + if (!stackSize) + return true; // prevent sres 0 + LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << " MFIs resulting in " << stackSize << " bytes to SC\n"); From 1b626430279f54173a603d3855163ebd129319dd Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Thu, 18 Apr 2024 19:39:23 +0200 Subject: [PATCH 14/67] check for stackCacheSize before reserving --- .../Patmos/PatmosStackCachePromotion.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 41631338ccbf..e851d99971d3 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -211,6 +211,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (!stackSize) return true; // prevent sres 0 + if (stackSize > STC.getStackCacheSize()) + return true; // TODO right now we simply abort and therefore push everything to the shadow stack, but only the exceeding data should be put on the shadow stack + LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() << " MFIs resulting in " << stackSize << " bytes to SC\n"); @@ -219,13 +222,13 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { auto startofblock = MF.begin(); auto startInstr = startofblock->begin(); - auto *ensureInstr = MF.CreateMachineInstr(TII->get(Patmos::SRESi), + auto *reserveInstr = MF.CreateMachineInstr(TII->get(Patmos::SRESi), startInstr->getDebugLoc()); - MachineInstrBuilder ensureInstrBuilder(MF, ensureInstr); - AddDefaultPred(ensureInstrBuilder); - ensureInstrBuilder.addImm(stackSize); + MachineInstrBuilder reserveInstrBuilder(MF, reserveInstr); + AddDefaultPred(reserveInstrBuilder); + reserveInstrBuilder.addImm(stackSize); - startofblock->insert(startInstr, ensureInstr); + startofblock->insert(startInstr, reserveInstr); calcOffsets(MF); @@ -249,6 +252,14 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { freeInstrBuilder.addImm(stackSize); endofBlock->insert(endInstr->getIterator(), freeInstr); + + //auto *ensInstr = MF.CreateMachineInstr(TII->get(Patmos::SENSr), + // endInstr->getDebugLoc()); + //MachineInstrBuilder ensInstrBuilder(MF, ensInstr); + //AddDefaultPred(ensInstrBuilder); + //ensInstrBuilder.addImm(stackSize); + + //endofBlock->insert(endInstr->getIterator(), ensInstr); } return true; } From 66363518bd4688d10466029d7dd78ce3b6a849ff Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 19 Apr 2024 11:10:01 +0200 Subject: [PATCH 15/67] fix weird loop condition --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 12 ++++-------- llvm/lib/Target/Patmos/PatmosStackCachePromotion.h | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index e851d99971d3..ba2e0b1056bf 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -37,10 +37,9 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { } void PatmosStackCachePromotion::processMachineInstruction( - MachineBasicBlock::iterator II) { + MachineInstr& MI) { // TODO Convert access to SC access - MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MBB.getParent(); const MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -232,12 +231,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { calcOffsets(MF); - for (auto BB_iter = startofblock, BB_iter_end = MF.end(); - BB_iter != BB_iter_end; ++BB_iter) { - for (auto instr_iter = startInstr, instr_iter_end = BB_iter->end(); - instr_iter != instr_iter_end; ++instr_iter) { - if (!instr_iter.isValid() || (instr_iter.getInstrIterator().getNodePtr()->isKnownSentinel())) break; // TODO Check why this is needed - processMachineInstruction(instr_iter); + for (auto& BB : MF) { + for (auto& instr : BB) { + processMachineInstruction(instr); } } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 57d21a359336..a7cac91ffd40 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -46,7 +46,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return "Patmos StackCache-Promotion pass (machine code)"; } - void processMachineInstruction(MachineBasicBlock::iterator II); + void processMachineInstruction(MachineInstr& MI); void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; From 7553e4fbcdf9402591dace3e977b1b11190b988e Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 23 Apr 2024 11:23:56 +0200 Subject: [PATCH 16/67] add lws asm test --- .../Patmos/assembly/instructions/lws.ll | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll diff --git a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll new file mode 100644 index 000000000000..58870ecfad0e --- /dev/null +++ b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll @@ -0,0 +1,42 @@ +; RUN: %test_no_runtime_execution + +define i32 @main() { +entry: + %stack_var = alloca [2 x i32] + %stack_var_1 = getelementptr [2 x i32], [2 x i32]* %stack_var, i32 0, i32 0 + store i32 15, i32* %stack_var_1 + %stack_var_2 = getelementptr [2 x i32], [2 x i32]* %stack_var, i32 0, i32 1 + store i32 16, i32* %stack_var_2 + + %asm_result = call { i32, i32 } asm " + lwc $0 = [$2] + lwc $1 = [$2 + 1] + + sres 8 + + sws [0] = $0 + sws [1] = $1 + + lws $0 = [0] + lws $1 = [1] + + sfree 8 + nop + ", "=&r,=r,r" + (i32* %stack_var_1) + + ; Extract results + %result_1 = extractvalue { i32, i32 } %asm_result, 0 + %result_2 = extractvalue { i32, i32 } %asm_result, 1 + + ; Check correctness + %correct_1 = icmp eq i32 %result_1, 15 + %correct_2 = icmp eq i32 %result_2, 16 + %correct = and i1 %correct_1, %correct_2 + + ; Negate result to ensure 0 is returned on success + %result_0 = xor i1 %correct, 1 + + %result = zext i1 %result_0 to i32 + ret i32 %result +} \ No newline at end of file From 5404acb4163bd93376f1f5f82a76559d35e31c53 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 23 Apr 2024 12:20:32 +0200 Subject: [PATCH 17/67] add stack cache assignment to frame lowering --- llvm/lib/Target/Patmos/PatmosFrameLowering.cpp | 3 +++ llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 1 + llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp index 4c012d9363d6..ac0256eb0082 100644 --- a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp +++ b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp @@ -128,6 +128,9 @@ void PatmosFrameLowering::assignFIsToStackCache(MachineFunction &MF, // find all spill slots and locations for callee saved registers if (MFI.isSpillSlotObjectIndex(FI)) SCFIs[FI] = true; + + if (!MFI.isFixedObjectIndex(FI)) + SCFIs[FI] = true; } } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index ba2e0b1056bf..c9388c29afa4 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -199,6 +199,7 @@ void PatmosStackCachePromotion::calcOffsets(MachineFunction& MF) { } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { + return false; // Disable for now, since we are using PatmosFrameLowering::assignFIsToStackCache instead for now if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll index 58870ecfad0e..6e558a72a079 100644 --- a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll +++ b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll @@ -9,8 +9,8 @@ entry: store i32 16, i32* %stack_var_2 %asm_result = call { i32, i32 } asm " - lwc $0 = [$2] - lwc $1 = [$2 + 1] + lws $0 = [$2] + lws $1 = [$2 + 1] sres 8 From 1942fb48f3cb8835be742cda88cf7df0bd4f957e Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 8 May 2024 12:20:23 +0200 Subject: [PATCH 18/67] add FI-SC assignment to PatmosStackCachePromotion pass --- .../lib/Target/Patmos/PatmosFrameLowering.cpp | 7 +- .../Target/Patmos/PatmosMachineFunctionInfo.h | 11 + .../Patmos/PatmosStackCachePromotion.cpp | 222 +----------------- .../lib/Target/Patmos/PatmosTargetMachine.cpp | 3 +- 4 files changed, 23 insertions(+), 220 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp index ac0256eb0082..d5b1062fcfe3 100644 --- a/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp +++ b/llvm/lib/Target/Patmos/PatmosFrameLowering.cpp @@ -129,8 +129,11 @@ void PatmosFrameLowering::assignFIsToStackCache(MachineFunction &MF, if (MFI.isSpillSlotObjectIndex(FI)) SCFIs[FI] = true; - if (!MFI.isFixedObjectIndex(FI)) - SCFIs[FI] = true; + + const std::vector &StackCacheAllocatable = PMFI.getStackCacheAnalysisFIs(); + for(unsigned i=0; i SinglePathFIs; + /// FIs determined to be movable to stack cache + std::vector StackCacheAnalysisFIs; + // Index to the SinglePathFIs where the S0 spill slots start unsigned SPS0SpillOffset; @@ -259,6 +262,14 @@ class PatmosMachineFunctionInfo : public MachineFunctionInfo { return SinglePathFIs.size(); } + const std::vector& getStackCacheAnalysisFIs(void) const { + return StackCacheAnalysisFIs; + } + + void addStackCacheAnalysisFI(int fi) { + StackCacheAnalysisFIs.push_back(fi); + } + PatmosAnalysisInfo &getAnalysisInfo() { return AnalysisInfo; } const PatmosAnalysisInfo &getAnalysisInfo() const { return AnalysisInfo; } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index c9388c29afa4..0a3952fa6977 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -1,4 +1,4 @@ -//===-- PatmosStackCachePromotion.cpp - Remove unused function declarations +//===-- PatmosStackCachePromotion.cpp - Analysis pass to determine which FIs can be promoted to the stack cache //------------===// // // The LLVM Compiler Infrastructure @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "PatmosStackCachePromotion.h" +#include "PatmosMachineFunctionInfo.h" #include "TargetInfo/PatmosTargetInfo.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -18,11 +19,6 @@ using namespace llvm; -STATISTIC(LoadsConverted, - "Number of data-cache loads converted to stack cache loads"); -STATISTIC(SavesConverted, - "Number of data-cache saves converted to stack cache saves"); - static cl::opt EnableStackCachePromotion( "mpatmos-enable-stack-cache-promotion", cl::init(false), cl::desc("Enable the compiler to promote data to the stack cache")); @@ -36,227 +32,19 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } -void PatmosStackCachePromotion::processMachineInstruction( - MachineInstr& MI) { - // TODO Convert access to SC access - - MachineBasicBlock &MBB = *MI.getParent(); - MachineFunction &MF = *MBB.getParent(); - const MachineFrameInfo &MFI = MF.getFrameInfo(); - - - unsigned FIOperandNum; - int FrameIndex; - if (TII->isLoadFromStackSlot(MI, FrameIndex)) { // For some reason the FrameDisplacement operand [4] sometimes is not 0 here? - FIOperandNum = 3; - } else if (TII->isStoreToStackSlot(MI, FrameIndex)) { // For some reason the FrameDisplacement operand [3] sometimes is not 0 here? - FIOperandNum = 2; - } else { - return; - } - - int FrameOffset = MFI.getObjectOffset(FrameIndex); - int FrameDisplacement = MI.getOperand(FIOperandNum+1).getImm(); - - int Offset = FrameOffset; - - unsigned opcode = MI.getOpcode(); - - // ensure that the offset fits the instruction - switch (opcode) - { - case Patmos::LWC: case Patmos::LWM: - case Patmos::SWC: case Patmos::SWM: - case Patmos::PSEUDO_PREG_SPILL: - case Patmos::PSEUDO_PREG_RELOAD: - // 9 bit - assert((Offset & 0x3) == 0); - Offset = (Offset >> 2) + FrameDisplacement; - break; - case Patmos::LHC: case Patmos::LHM: - case Patmos::LHUC: case Patmos::LHUM: - case Patmos::SHC: case Patmos::SHM: - // 8 bit - assert((Offset & 0x1) == 0); - Offset = (Offset >> 1) + FrameDisplacement; - - break; - case Patmos::LBC: case Patmos::LBM: - case Patmos::LBUC: case Patmos::LBUM: - case Patmos::SBC: case Patmos::SBM: - // 7 bit - Offset += FrameDisplacement; - break; - case Patmos::ADDi: - // 12 bit - Offset += FrameDisplacement; - break; - case Patmos::ADDl: - case Patmos::DBG_VALUE: - // all should be fine - Offset += FrameDisplacement; - break; - default: - llvm_unreachable("Unexpected operation with FrameIndex encountered."); - } - - switch (opcode) - { - case Patmos::LWC: case Patmos::LWM: opcode = Patmos::LWS; break; - case Patmos::LHC: case Patmos::LHM: opcode = Patmos::LHS; break; - case Patmos::LHUC: case Patmos::LHUM: opcode = Patmos::LHUS; break; - case Patmos::LBC: case Patmos::LBM: opcode = Patmos::LBS; break; - case Patmos::LBUC: case Patmos::LBUM: opcode = Patmos::LBUS; break; - case Patmos::SWC: case Patmos::SWM: opcode = Patmos::SWS; break; - case Patmos::SHC: case Patmos::SHM: opcode = Patmos::SHS; break; - case Patmos::SBC: case Patmos::SBM: opcode = Patmos::SBS; break; - case Patmos::ADDi: case Patmos::ADDl: case Patmos::DBG_VALUE: - break; - default: - llvm_unreachable("Unexpected operation with FrameIndex encountered."); - } - - // Update Data Cache instr to use Stack Cache - const MCInstrDesc &newMCID = TII->get(opcode); - MI.setDesc(newMCID); - - MI.getOperand(FIOperandNum).ChangeToRegister(Patmos::R0, false, false, false); - MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); - - /* - - Register dataReg; - uint64_t basePtrReg; - uint64_t unknown1; - uint64_t offset; - uint64_t FrameDisplacement; - - if (llvm::isMainMemLoadInst(MI.getOpcode())) { - basePtrReg = MI.getOperand(1).getReg(); - dataReg = MI.getOperand(0).getReg(); - offset = MFI.getObjectOffset(MI.getOperand(3).getIndex()); - FrameDisplacement = MI.getOperand(4).getImm(); - unknown1 = MI.getOperand(2).getImm(); - - auto dataRegName = TII->getRegisterInfo().getRegAsmName(dataReg); - auto basePtrRegName = - basePtrReg > 0 ? TII->getRegisterInfo().getRegAsmName(basePtrReg) : "?"; - - LLVM_DEBUG(dbgs() << TII->getName(MI.getOpcode()) << " " << dataRegName - << " = " - << "[" << basePtrRegName << " + " << offset << "]" - << "\n"); - - } else if (llvm::isMainMemStoreInst(MI.getOpcode())) { - basePtrReg = MI.getOperand(0) - .getReg(); // This is not known yet at this point in time - dataReg = MI.getOperand(4).getReg(); - offset = MFI.getObjectOffset( - MI.getOperand(2) - .getIndex()); // This is not final yet at this point in time - FrameDisplacement = MI.getOperand(3).getImm(); // Always has to be zero - unknown1 = MI.getOperand(1).getImm(); - - auto dataRegName = TII->getRegisterInfo().getRegAsmName(dataReg); - auto basePtrRegName = - basePtrReg > 0 ? TII->getRegisterInfo().getRegAsmName(basePtrReg) : "?"; - - LLVM_DEBUG(dbgs() << TII->getName(MI.getOpcode()) << "[" << basePtrRegName - << " + " << offset << "] = " << dataRegName << "\n"); - } else { - return; - }*/ -} - -void PatmosStackCachePromotion::calcOffsets(MachineFunction& MF) { - MachineFrameInfo &MFI = MF.getFrameInfo(); - - SmallVector ObjectsToAllocate; - - for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { - if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) - continue; - if (MFI.isDeadObjectIndex(i)) - continue; - - ObjectsToAllocate.push_back(i); - } - - - int64_t offset = 0; - Align maxalign = MFI.getMaxAlign(); - for (auto &FrameIdx : ObjectsToAllocate) { - // AdjustStackOffset - Align Alignment = MFI.getObjectAlign(FrameIdx); - - maxalign = std::max(maxalign, Alignment); - offset = alignTo(offset, Alignment); - - MFI.setObjectOffset(FrameIdx, offset); - offset += MFI.getObjectSize(FrameIdx); - - } -} - bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - return false; // Disable for now, since we are using PatmosFrameLowering::assignFIsToStackCache instead for now if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); // Calculate the amount of bytes to store on SC MachineFrameInfo &MFI = MF.getFrameInfo(); - unsigned stackSize = MFI.estimateStackSize(MF); - - if (!stackSize) - return true; // prevent sres 0 - - if (stackSize > STC.getStackCacheSize()) - return true; // TODO right now we simply abort and therefore push everything to the shadow stack, but only the exceeding data should be put on the shadow stack - - LLVM_DEBUG(dbgs() << "Storing " << MFI.getObjectIndexEnd() - << " MFIs resulting in " << stackSize - << " bytes to SC\n"); - - // Insert Reserve before function start - auto startofblock = MF.begin(); - auto startInstr = startofblock->begin(); - - auto *reserveInstr = MF.CreateMachineInstr(TII->get(Patmos::SRESi), - startInstr->getDebugLoc()); - MachineInstrBuilder reserveInstrBuilder(MF, reserveInstr); - AddDefaultPred(reserveInstrBuilder); - reserveInstrBuilder.addImm(stackSize); + PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); - startofblock->insert(startInstr, reserveInstr); - - calcOffsets(MF); - - for (auto& BB : MF) { - for (auto& instr : BB) { - processMachineInstruction(instr); - } + for(unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { + PMFI.addStackCacheAnalysisFI(FI); } - // Insert Free after function End - auto endofBlock = MF.rbegin(); - auto endInstr = endofBlock->rbegin(); - - auto *freeInstr = MF.CreateMachineInstr(TII->get(Patmos::SFREEi), - endInstr->getDebugLoc()); - MachineInstrBuilder freeInstrBuilder(MF, freeInstr); - AddDefaultPred(freeInstrBuilder); - freeInstrBuilder.addImm(stackSize); - - endofBlock->insert(endInstr->getIterator(), freeInstr); - - //auto *ensInstr = MF.CreateMachineInstr(TII->get(Patmos::SENSr), - // endInstr->getDebugLoc()); - //MachineInstrBuilder ensInstrBuilder(MF, ensInstr); - //AddDefaultPred(ensInstrBuilder); - //ensInstrBuilder.addImm(stackSize); - - //endofBlock->insert(endInstr->getIterator(), ensInstr); } return true; } diff --git a/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp b/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp index b6de6875ffa3..67d918e2660b 100644 --- a/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp +++ b/llvm/lib/Target/Patmos/PatmosTargetMachine.cpp @@ -148,6 +148,8 @@ namespace { /// run passes immediately before register allocation. This should return /// true if -print-machineinstrs should print after these passes. void addPreRegAlloc() override { + addPass(createPatmosStackCachePromotionPass(getPatmosTargetMachine())); + // For -O0, add a pass that removes dead instructions to avoid issues // with spill code in naked functions containing function calls with // unused return values. @@ -177,7 +179,6 @@ namespace { /// This method may be implemented by targets that want to run passes after /// register allocation pass pipeline but before prolog-epilog insertion. void addPostRegAlloc() override { - addPass(createPatmosStackCachePromotionPass(getPatmosTargetMachine())); if(PatmosSinglePathInfo::isEnabled() && PatmosSinglePathInfo::useNewSinglePathTransform()) { // The previous register allocation allocated the predicate registers too. From a22e213c1cf4fd565aa05792410dc522bf7d2114 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 30 May 2024 16:46:54 +0200 Subject: [PATCH 19/67] add correction for non-FI lwcs to lws --- .../Patmos/PatmosStackCachePromotion.cpp | 86 ++++++++++++++++++- .../bounded/single_source/stackcache/array.ll | 67 +++++++++++++++ 2 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 0a3952fa6977..d3cda4ade5c0 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -1,4 +1,5 @@ -//===-- PatmosStackCachePromotion.cpp - Analysis pass to determine which FIs can be promoted to the stack cache +//===-- PatmosStackCachePromotion.cpp - Analysis pass to determine which FIs can +//be promoted to the stack cache //------------===// // // The LLVM Compiler Infrastructure @@ -32,6 +33,60 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } +bool isFIusedInCall(MachineFunction &MF, unsigned FI) { + for (const auto &MBB : MF) { + for (const auto &MI : MBB) { + if (MI.isCall()) { + for (const MachineOperand &MO : MI.operands()) { + if (MO.isFI()) { + int FrameIndex = MO.getIndex(); + if (FrameIndex == FI) + return true; + } + } + } + } + } + return false; +} + +std::vector getDeps(const MachineInstr &MI, + const MachineFunction &MF) { + const MachineRegisterInfo &MRI = MF.getRegInfo(); + std::vector Dependencies; + + for (auto &MO : MI.operands()) { + if (MO.isReg() && MO.isUse()) { + unsigned Reg = MO.getReg(); + if (Register::isVirtualRegister(Reg)) { + MachineInstr *DefMI = MRI.getVRegDef(Reg); + if (DefMI) { + auto lower = getDeps(*DefMI, MF); + Dependencies.push_back(DefMI); + Dependencies.insert(Dependencies.end(), lower.begin(), lower.end()); + } + } + } + } + return Dependencies; +} + +bool hasFIonSC(const std::vector deps, + const MachineFunction &MF) { + const PatmosMachineFunctionInfo &PMFI = + *MF.getInfo(); + for (const auto MI : deps) { + for (const auto &op : MI->operands()) { + if (op.isFI() && + std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), + PMFI.getStackCacheAnalysisFIs().end(), + [&op](auto elem) { return elem == op.isFI(); })) + return true; + } + } + return false; +} + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " @@ -41,10 +96,37 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo &MFI = MF.getFrameInfo(); PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); - for(unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { + for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { + // if (!MFI.isFixedObjectIndex(FI) && !isFIusedInCall(MF, FI)) PMFI.addStackCacheAnalysisFI(FI); } + for (auto &BB : MF) { + for (auto &MI : BB) { + if (MI.getOpcode() == Patmos::LWC) { + auto Dependencies = getDeps(MI, MF); + if (Dependencies.size() == 0) + continue; + + if (!hasFIonSC(Dependencies, MF)) + continue; + + MI.setDesc(TII->get(Patmos::LWS)); + + MI.dump(); + LLVM_DEBUG(dbgs() << "\tDepends on: \n"); + for (auto &DMI : Dependencies) { + LLVM_DEBUG(dbgs() << *DMI); + } + LLVM_DEBUG(dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "\n"); + } + } + } + + // Iterate over every Instr x + // For each x -> find instrs y that x depends on && transitively + // for each y -> if has FI && Is on SC -> convert to L.S/S.S } return true; } diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll new file mode 100644 index 000000000000..45fabd1150cf --- /dev/null +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll @@ -0,0 +1,67 @@ +; RUN: EXEC_ARGS="1=12 0=11"; \ +; RUN: %test_execution +; END. +;////////////////////////////////////////////////////////////////////////////////////////////////// +; +; Tests that summing an array works correctly +; +;////////////////////////////////////////////////////////////////////////////////////////////////// + + +@__const.main.a = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4 + +; Function Attrs: noinline nounwind optnone +define dso_local i32 @main(i32 %x) #0 { +entry: + %retval = alloca i32, align 4 + %x.addr = alloca i32, align 4 + %a = alloca [3 x i32], align 4 + %i = alloca i32, align 4 + %t = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + store i32 %x, i32* %x.addr, align 4 + %0 = bitcast [3 x i32]* %a to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @__const.main.a to i8*), i32 12, i1 false) + store i32 0, i32* %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %1 = load i32, i32* %i, align 4 + %cmp = icmp ult i32 %1, 3 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, i32* %i, align 4 + %3 = load i32, i32* %i, align 4 + %mul = mul nsw i32 %2, %3 + store i32 %mul, i32* %t, align 4 + %4 = load i32, i32* %i, align 4 + %arrayidx = getelementptr inbounds [3 x i32], [3 x i32]* %a, i32 0, i32 %4 + %5 = load i32, i32* %arrayidx, align 4 + %6 = load i32, i32* %t, align 4 + %add = add nsw i32 %5, %6 + %7 = load i32, i32* %x.addr, align 4 + %add1 = add nsw i32 %7, %add + store i32 %add1, i32* %x.addr, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %8 = load i32, i32* %i, align 4 + %inc = add nsw i32 %8, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond, !llvm.loop !2 + +for.end: ; preds = %for.cond + %9 = load i32, i32* %x.addr, align 4 + ret i32 %9 +} + + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #1 + +attributes #0 = { noinline nounwind optnone "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nofree nosync nounwind willreturn } + +!2 = distinct !{!2, !3} +!3 = !{!"llvm.loop.mustprogress"} From ac948a3ad215240d3cec38b337f81c93f502612d Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 30 May 2024 17:00:57 +0200 Subject: [PATCH 20/67] fix Load correction --- .../Patmos/PatmosStackCachePromotion.cpp | 44 +++++++++++-------- .../Target/Patmos/PatmosStackCachePromotion.h | 2 + 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index d3cda4ade5c0..1458b169a130 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -80,13 +80,35 @@ bool hasFIonSC(const std::vector deps, if (op.isFI() && std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), PMFI.getStackCacheAnalysisFIs().end(), - [&op](auto elem) { return elem == op.isFI(); })) + [&op](auto elem) { return elem == op.getIndex(); })) return true; } } return false; } +void PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, + MachineFunction &MF) { + if (MI.getOpcode() == OPold) { + auto Dependencies = getDeps(MI, MF); + if (Dependencies.size() == 0) + return; + + if (!hasFIonSC(Dependencies, MF)) + return; + + MI.setDesc(TII->get(OPnew)); + + MI.dump(); + LLVM_DEBUG(dbgs() << "\tDepends on: \n"); + for (auto &DMI : Dependencies) { + LLVM_DEBUG(dbgs() << *DMI); + } + LLVM_DEBUG(dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "\n"); + } +} + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " @@ -98,29 +120,13 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { // if (!MFI.isFixedObjectIndex(FI) && !isFIusedInCall(MF, FI)) + LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); PMFI.addStackCacheAnalysisFI(FI); } for (auto &BB : MF) { for (auto &MI : BB) { - if (MI.getOpcode() == Patmos::LWC) { - auto Dependencies = getDeps(MI, MF); - if (Dependencies.size() == 0) - continue; - - if (!hasFIonSC(Dependencies, MF)) - continue; - - MI.setDesc(TII->get(Patmos::LWS)); - - MI.dump(); - LLVM_DEBUG(dbgs() << "\tDepends on: \n"); - for (auto &DMI : Dependencies) { - LLVM_DEBUG(dbgs() << *DMI); - } - LLVM_DEBUG(dbgs() << "\n"); - LLVM_DEBUG(dbgs() << "\n"); - } + replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); } } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index a7cac91ffd40..70741455d4f1 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -50,6 +50,8 @@ class PatmosStackCachePromotion : public MachineFunctionPass { void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; + void replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, + MachineInstr &MI, MachineFunction &MF); }; } // End llvm namespace From e66ae1db01990ae3f1a7828b6825f8bd92dedec4 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 30 May 2024 17:14:14 +0200 Subject: [PATCH 21/67] refactor Load correction --- .../Patmos/PatmosStackCachePromotion.cpp | 31 ++++++++++++++++--- .../Target/Patmos/PatmosStackCachePromotion.h | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 1458b169a130..ba3cd471cd7e 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -87,15 +87,15 @@ bool hasFIonSC(const std::vector deps, return false; } -void PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, +bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { if (MI.getOpcode() == OPold) { auto Dependencies = getDeps(MI, MF); if (Dependencies.size() == 0) - return; + return false; if (!hasFIonSC(Dependencies, MF)) - return; + return false; MI.setDesc(TII->get(OPnew)); @@ -106,7 +106,9 @@ void PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew } LLVM_DEBUG(dbgs() << "\n"); LLVM_DEBUG(dbgs() << "\n"); + return true; } + return false; } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { @@ -124,9 +126,30 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { PMFI.addStackCacheAnalysisFI(FI); } + const std::vector> mappings = { + {Patmos::LWC, Patmos::LWS}, + /*{Patmos::LHC, Patmos::LHS}, + {Patmos::LBC, Patmos::LBS}, + {Patmos::LHUC, Patmos::LHUS}, + {Patmos::LBUC, Patmos::LBUS},*/ + + /*{Patmos::SWC, Patmos::SWS}, + {Patmos::SHC, Patmos::SHS}, + {Patmos::SBC, Patmos::SBS},*/ + }; + for (auto &BB : MF) { for (auto &MI : BB) { - replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); + std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first, elem.second, MI, MF);}); + /*replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); + replaceOpcodeIfSC(Patmos::LHC, Patmos::LHS, MI, MF); + replaceOpcodeIfSC(Patmos::LBC, Patmos::LBS, MI, MF); + replaceOpcodeIfSC(Patmos::LHUC, Patmos::LHUS, MI, MF); + replaceOpcodeIfSC(Patmos::LBUC, Patmos::LBUS, MI, MF); + + replaceOpcodeIfSC(Patmos::SWC, Patmos::SWS, MI, MF); + replaceOpcodeIfSC(Patmos::SHC, Patmos::SHS, MI, MF); + replaceOpcodeIfSC(Patmos::SBC, Patmos::SBS, MI, MF);*/ } } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 70741455d4f1..53bc3cd818a4 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -50,7 +50,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; - void replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, + bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, MachineInstr &MI, MachineFunction &MF); }; From 737986db277c9c777927b550b07e57dd69a2d397 Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Fri, 7 Jun 2024 11:41:28 +0200 Subject: [PATCH 22/67] cut dependency cycles --- .../Patmos/PatmosStackCachePromotion.cpp | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index ba3cd471cd7e..a521621f350e 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -50,6 +50,27 @@ bool isFIusedInCall(MachineFunction &MF, unsigned FI) { return false; } +void getDeps(MachineInstr* MI, + const MachineFunction &MF, + std::vector& Dependencies) { + if (std::find(Dependencies.begin(), Dependencies.end(), MI) != Dependencies.end()) + return; + Dependencies.push_back(MI); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + for (auto &MO : MI->operands()) { + if (MO.isReg() && MO.isUse()) { + unsigned Reg = MO.getReg(); + if (Register::isVirtualRegister(Reg)) { + MachineInstr *DefMI = MRI.getVRegDef(Reg); + if (DefMI) { + getDeps(DefMI, MF, Dependencies); + } + } + } + } + return; +} + std::vector getDeps(const MachineInstr &MI, const MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -61,9 +82,7 @@ std::vector getDeps(const MachineInstr &MI, if (Register::isVirtualRegister(Reg)) { MachineInstr *DefMI = MRI.getVRegDef(Reg); if (DefMI) { - auto lower = getDeps(*DefMI, MF); - Dependencies.push_back(DefMI); - Dependencies.insert(Dependencies.end(), lower.begin(), lower.end()); + getDeps(DefMI, MF, Dependencies); } } } @@ -89,6 +108,7 @@ bool hasFIonSC(const std::vector deps, bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { + if (MI.getOpcode() == OPold) { auto Dependencies = getDeps(MI, MF); if (Dependencies.size() == 0) @@ -128,14 +148,14 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { const std::vector> mappings = { {Patmos::LWC, Patmos::LWS}, - /*{Patmos::LHC, Patmos::LHS}, + {Patmos::LHC, Patmos::LHS}, {Patmos::LBC, Patmos::LBS}, {Patmos::LHUC, Patmos::LHUS}, - {Patmos::LBUC, Patmos::LBUS},*/ + {Patmos::LBUC, Patmos::LBUS}, - /*{Patmos::SWC, Patmos::SWS}, + {Patmos::SWC, Patmos::SWS}, {Patmos::SHC, Patmos::SHS}, - {Patmos::SBC, Patmos::SBS},*/ + {Patmos::SBC, Patmos::SBS}, }; for (auto &BB : MF) { From 9685363c0b84f472dcca7cda0c8479b1465f2420 Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Fri, 7 Jun 2024 11:44:52 +0200 Subject: [PATCH 23/67] dont replace instructions with direct FI operands --- .../stackcache/loop_allocation.ll | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll new file mode 100644 index 000000000000..1a2c2f67f9e5 --- /dev/null +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll @@ -0,0 +1,34 @@ +; RUN: EXEC_ARGS="1=1 2=2"; \ +; RUN: WITH_DEBUG=true; \ +; RUN: %test_execution +; END. +;////////////////////////////////////////////////////////////////////////////////////////////////// +; +; Test stack allocation within a loop +; +;////////////////////////////////////////////////////////////////////////////////////////////////// + +; CHECK-LABEL: main: +define i32 @main(i32 %value) { +entry: + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %while.cond + +while.cond: ; preds = %while.body, %entry + %0 = load i32, i32* %i, align 4 + %cmp = icmp slt i32 %0, 5 + br i1 %cmp, label %while.body, label %while.end + +while.body: ; preds = %while.cond + %x = alloca i32, align 4 + %1 = load i32, i32* %i, align 4 + store i32 %1, i32* %x, align 4 + %2 = load i32, i32* %i, align 4 + %add = add nsw i32 %2, 1 + store i32 %add, i32* %i, align 4 + br label %while.cond + +while.end: ; preds = %while.cond + ret i32 %value +} \ No newline at end of file From a412c43c75542a3a0e6f45400590533045c2417d Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Fri, 7 Jun 2024 11:46:07 +0200 Subject: [PATCH 24/67] dont replace instructions with direct FI operands --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index a521621f350e..bc71c47011d3 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -108,7 +108,9 @@ bool hasFIonSC(const std::vector deps, bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { - + if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { + return false; + } if (MI.getOpcode() == OPold) { auto Dependencies = getDeps(MI, MF); if (Dependencies.size() == 0) From 3670bfd663b5abc36ed282790acc9cdd5c43b1f6 Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Fri, 7 Jun 2024 11:50:47 +0200 Subject: [PATCH 25/67] remove faulty test --- .../stackcache/loop_allocation.ll | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll deleted file mode 100644 index 1a2c2f67f9e5..000000000000 --- a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/loop_allocation.ll +++ /dev/null @@ -1,34 +0,0 @@ -; RUN: EXEC_ARGS="1=1 2=2"; \ -; RUN: WITH_DEBUG=true; \ -; RUN: %test_execution -; END. -;////////////////////////////////////////////////////////////////////////////////////////////////// -; -; Test stack allocation within a loop -; -;////////////////////////////////////////////////////////////////////////////////////////////////// - -; CHECK-LABEL: main: -define i32 @main(i32 %value) { -entry: - %i = alloca i32, align 4 - store i32 0, i32* %i, align 4 - br label %while.cond - -while.cond: ; preds = %while.body, %entry - %0 = load i32, i32* %i, align 4 - %cmp = icmp slt i32 %0, 5 - br i1 %cmp, label %while.body, label %while.end - -while.body: ; preds = %while.cond - %x = alloca i32, align 4 - %1 = load i32, i32* %i, align 4 - store i32 %1, i32* %x, align 4 - %2 = load i32, i32* %i, align 4 - %add = add nsw i32 %2, 1 - store i32 %add, i32* %i, align 4 - br label %while.cond - -while.end: ; preds = %while.cond - ret i32 %value -} \ No newline at end of file From 5fdba6e7350e0538a8e3df62da195b61d9fb68f8 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 10 Jun 2024 12:24:25 +0200 Subject: [PATCH 26/67] fix LWS test args --- .../CodeGen/Patmos/assembly/instructions/lws.ll | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll index 6e558a72a079..a5fe883dd917 100644 --- a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll +++ b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll @@ -1,3 +1,4 @@ +; RUN: LLC_ARGS="-mpatmos-enable-stack-cache-promotion"; \ ; RUN: %test_no_runtime_execution define i32 @main() { @@ -11,17 +12,7 @@ entry: %asm_result = call { i32, i32 } asm " lws $0 = [$2] lws $1 = [$2 + 1] - - sres 8 - - sws [0] = $0 - sws [1] = $1 - - lws $0 = [0] - lws $1 = [1] - - sfree 8 - nop + nop ", "=&r,=r,r" (i32* %stack_var_1) From 2856464d85f9ac6d9cdbfa84cf7d958ad3a73933 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 10 Jun 2024 12:27:04 +0200 Subject: [PATCH 27/67] add stack cache optimization flags to assert_correct.py --- llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py index f595a893b289..0f071fd680f8 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py +++ b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py @@ -243,7 +243,7 @@ def compile_and_test_matrix(llc_args, pasim_args, matrix): compile_and_test_matrix("", "", [ # Optimization levels - "", "-O1", + "", "--mpatmos-enable-stack-cache-promotion", "-O1", "-O2", "-O2 -mpatmos-disable-vliw=false", # We try low subfuction size to ensure the splitter works too # (without needing to make tests with big functions) From 52b8a048dfd76d44eda85f8239aff7986a0aea14 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 10 Jun 2024 14:30:28 +0200 Subject: [PATCH 28/67] fix assert_correct.py argument combinations --- .../CodeGen/Patmos/programs/bounded/assert_correct.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py index 0f071fd680f8..38c598a07893 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py +++ b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py @@ -243,11 +243,15 @@ def compile_and_test_matrix(llc_args, pasim_args, matrix): compile_and_test_matrix("", "", [ # Optimization levels - "", "--mpatmos-enable-stack-cache-promotion", "-O1", + "", "-O1", "-O2", "-O2 -mpatmos-disable-vliw=false", # We try low subfuction size to ensure the splitter works too # (without needing to make tests with big functions) - "-O2 --mpatmos-max-subfunction-size=64", + "-O2 --mpatmos-max-subfunction-size=64", + [ + "", + "--mpatmos-enable-stack-cache-promotion" + ], [ # We add this indirection so that commenting out the following line will remove all traditional tests "", @@ -264,7 +268,7 @@ def compile_and_test_matrix(llc_args, pasim_args, matrix): "-mpatmos-singlepath=" + sp_root, [ "-mpatmos-disable-singlepath-scheduler-equivalence-class", - "", + "", ("-mpatmos-enable-permissive-dual-issue", "--permissive-dual-issue"), "-mpatmos-disable-pseudo-roots", "-mpatmos-disable-countless-loops", [ From e46906e8c59cf531c7ca49963dc259937ef9776a Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 13 Jun 2024 16:08:38 +0200 Subject: [PATCH 29/67] add check for external symbols --- .../Patmos/PatmosStackCachePromotion.cpp | 80 ++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index bc71c47011d3..e2b06af74ec7 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -90,6 +90,79 @@ std::vector getDeps(const MachineInstr &MI, return Dependencies; } +const AllocaInst* findAllocaForValue(const Value *V) { + // Iterate through the users of the value + for (const User *U : V->users()) { + if (const StoreInst *SI = dyn_cast(U)) { + if (SI->getValueOperand() == V) { + // Found a StoreInst using V, now check its pointer operand + const Value *Ptr = SI->getPointerOperand(); + // Trace back the pointer operand + if (const AllocaInst *AI = dyn_cast(Ptr)) { + return AI; + } else { + // If not an AllocaInst, continue tracing back + return findAllocaForValue(Ptr); + } + } + } + } + return nullptr; // No matching AllocaInst found +} + +bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) { + // Get the frame information from the machine function + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + // Check if the frame index is valid + if (ObjectFI < 0 || ObjectFI >= MFI.getObjectIndexEnd()) { + llvm_unreachable("Invalid frame index!"); + } + + // Check if the frame index is associated with a fixed object + if (MFI.isFixedObjectIndex(ObjectFI)) { + return false; + } + + const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); + dbgs() << "AllocaInst: " << *AI << "\n"; + + const Function &F = MF.getFunction(); + const Module *M = F.getParent(); + + std::vector stores; + + for (const BasicBlock &BB : F) { + for (const Instruction &I : BB) { + if (const auto *store = dyn_cast(&I)) { + if (store->getPointerOperand() == AI) { + stores.push_back(store); + } + } + } + } + + for (const auto& store : stores) { + dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"; + } + + + for (const GlobalVariable &GV : M->globals()) { + if (GV.hasExternalLinkage()) { + dbgs() << "GV: " << GV << "\n"; + if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ + // TODO This does not work + return store->getValueOperand() == &GV; + })) { + dbgs() << "store from: " << GV << "\n"; + return true; + } + } + } + + return false; +} + bool hasFIonSC(const std::vector deps, const MachineFunction &MF) { const PatmosMachineFunctionInfo &PMFI = @@ -99,7 +172,7 @@ bool hasFIonSC(const std::vector deps, if (op.isFI() && std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), PMFI.getStackCacheAnalysisFIs().end(), - [&op](auto elem) { return elem == op.getIndex(); })) + [&op](auto elem) { return elem == op.getIndex(); }) && !isFIAPointerToExternalSymbol(op.getIndex(), MF)) return true; } } @@ -119,15 +192,16 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew if (!hasFIonSC(Dependencies, MF)) return false; - MI.setDesc(TII->get(OPnew)); - MI.dump(); + LLVM_DEBUG(dbgs() << MI); LLVM_DEBUG(dbgs() << "\tDepends on: \n"); for (auto &DMI : Dependencies) { LLVM_DEBUG(dbgs() << *DMI); } LLVM_DEBUG(dbgs() << "\n"); LLVM_DEBUG(dbgs() << "\n"); + + MI.setDesc(TII->get(OPnew)); return true; } return false; From 4721b359e605c1851b40de68ec9d123a9807152c Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 17 Jun 2024 13:11:02 +0200 Subject: [PATCH 30/67] add check for external symbols --- .../Patmos/PatmosStackCachePromotion.cpp | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index e2b06af74ec7..0982c38b2cbd 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -90,24 +90,21 @@ std::vector getDeps(const MachineInstr &MI, return Dependencies; } -const AllocaInst* findAllocaForValue(const Value *V) { - // Iterate through the users of the value - for (const User *U : V->users()) { - if (const StoreInst *SI = dyn_cast(U)) { - if (SI->getValueOperand() == V) { - // Found a StoreInst using V, now check its pointer operand - const Value *Ptr = SI->getPointerOperand(); - // Trace back the pointer operand - if (const AllocaInst *AI = dyn_cast(Ptr)) { - return AI; - } else { - // If not an AllocaInst, continue tracing back - return findAllocaForValue(Ptr); - } - } +const GlobalVariable* findGlobalVariable(const Value *V) { + if (auto *AI = dyn_cast(V)) + return AI; + + if (auto *BCI = dyn_cast(V)) + return findGlobalVariable(BCI->getOperand(0)); + if (auto *GEP = dyn_cast(V)) + return findGlobalVariable(GEP->getPointerOperand()); + if (auto *CE = dyn_cast(V)) { + if (CE->getOpcode() == Instruction::BitCast) { + return findGlobalVariable(CE->getOperand(0)); } } - return nullptr; // No matching AllocaInst found + + return nullptr; } bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) { @@ -142,17 +139,22 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } - for (const auto& store : stores) { + /*for (const auto& store : stores) { dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"; - } + // Trace back to find the AllocaInst + if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { + dbgs() << "AI: " << *(AI) << "\n"; + } + }*/ for (const GlobalVariable &GV : M->globals()) { if (GV.hasExternalLinkage()) { - dbgs() << "GV: " << GV << "\n"; if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ - // TODO This does not work - return store->getValueOperand() == &GV; + if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { + return AI == &GV; + } + return false; })) { dbgs() << "store from: " << GV << "\n"; return true; From 2040f039a7ae11c282322037de19d1eb16fe02f9 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 17 Jun 2024 16:22:37 +0200 Subject: [PATCH 31/67] fix check for external symbols --- .../Patmos/PatmosStackCachePromotion.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 0982c38b2cbd..06ff5e80845a 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -113,7 +113,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) // Check if the frame index is valid if (ObjectFI < 0 || ObjectFI >= MFI.getObjectIndexEnd()) { - llvm_unreachable("Invalid frame index!"); + return false; } // Check if the frame index is associated with a fixed object @@ -171,10 +171,11 @@ bool hasFIonSC(const std::vector deps, *MF.getInfo(); for (const auto MI : deps) { for (const auto &op : MI->operands()) { + if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) return false; if (op.isFI() && std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), PMFI.getStackCacheAnalysisFIs().end(), - [&op](auto elem) { return elem == op.getIndex(); }) && !isFIAPointerToExternalSymbol(op.getIndex(), MF)) + [&op](auto elem) { return elem == op.getIndex(); })) return true; } } @@ -186,22 +187,32 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { return false; } + if (MI.getOpcode() == OPold) { + LLVM_DEBUG(dbgs() << MI); + auto Dependencies = getDeps(MI, MF); + + LLVM_DEBUG(dbgs() << "\tDepends on: \n"); + for (auto &DMI : Dependencies) { + LLVM_DEBUG(dbgs() << "\t" << *DMI); + } + LLVM_DEBUG(dbgs() << "\n"); + if (Dependencies.size() == 0) return false; if (!hasFIonSC(Dependencies, MF)) return false; + LLVM_DEBUG(dbgs() << "Updating op...\n"); - LLVM_DEBUG(dbgs() << MI); - LLVM_DEBUG(dbgs() << "\tDepends on: \n"); + /*LLVM_DEBUG(dbgs() << "\tDepends on: \n"); for (auto &DMI : Dependencies) { LLVM_DEBUG(dbgs() << *DMI); } LLVM_DEBUG(dbgs() << "\n"); - LLVM_DEBUG(dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "\n");*/ MI.setDesc(TII->get(OPnew)); return true; From 4742187bab788596091575e0dc557d037109a62b Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 15:56:45 +0200 Subject: [PATCH 32/67] add attribute to enable sco for functions --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 06ff5e80845a..62f02329e5bd 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -221,7 +221,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion) { + if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("stack_cache")) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); From fa1726f28d015c5dd6460b652c14de23b19ee80e Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 15:57:42 +0200 Subject: [PATCH 33/67] fix attribute to enable sco for functions --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 62f02329e5bd..582b995c89d9 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -221,7 +221,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("stack_cache")) { + if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("annotate") && MF.getFunction().getFnAttribute("annotatet").getValueAsString() == "stack_cache") { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); From 4523b1b3bb14eeba4751d1d8fc72a0d1b65a131d Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 15:57:53 +0200 Subject: [PATCH 34/67] fix typo --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 582b995c89d9..628cc8d32bd5 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -221,7 +221,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("annotate") && MF.getFunction().getFnAttribute("annotatet").getValueAsString() == "stack_cache") { + if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("annotate") && MF.getFunction().getFnAttribute("annotate").getValueAsString() == "stack_cache") { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); From e397da35f27c33bb7de4946b53377a2467e26af3 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 16:17:47 +0200 Subject: [PATCH 35/67] fix annotation parsing --- .../Patmos/PatmosStackCachePromotion.cpp | 7 ++-- .../Target/Patmos/PatmosStackCachePromotion.h | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 628cc8d32bd5..d4167039881d 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -122,7 +122,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); - dbgs() << "AllocaInst: " << *AI << "\n"; + LLVM_DEBUG(dbgs() << "AllocaInst: " << *AI << "\n"); const Function &F = MF.getFunction(); const Module *M = F.getParent(); @@ -156,7 +156,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } return false; })) { - dbgs() << "store from: " << GV << "\n"; + LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); return true; } } @@ -220,8 +220,9 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew return false; } + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion && MF.getFunction().hasFnAttribute("annotate") && MF.getFunction().getFnAttribute("annotate").getValueAsString() == "stack_cache") { + if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 53bc3cd818a4..a12600285e39 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -32,6 +32,34 @@ class PatmosStackCachePromotion : public MachineFunctionPass { const PatmosInstrInfo *TII; const PatmosRegisterInfo *TRI; + std::set annotFuncs; + + void getAnnotatedFunctions(Module *M){ + for (Module::global_iterator I = M->global_begin(), + E = M->global_end(); + I != E; + ++I) { + + if (I->getName() == "llvm.global.annotations") { + ConstantArray *CA = dyn_cast(I->getOperand(0)); + for(auto OI = CA->op_begin(); OI != CA->op_end(); ++OI){ + ConstantStruct *CS = dyn_cast(OI->get()); + Function *FUNC = dyn_cast(CS->getOperand(0)->getOperand(0)); + GlobalVariable *AnnotationGL = dyn_cast(CS->getOperand(1)->getOperand(0)); + StringRef annotation = dyn_cast(AnnotationGL->getInitializer())->getAsCString(); + if(annotation.compare("stack_cache")==0){ + annotFuncs.insert(FUNC); + errs() << "Found annotated function " << FUNC->getName()<<"\n"; + } + } + } + } + } + + bool shouldInstrumentFunc(Function &F){ + return annotFuncs.find(&F)!=annotFuncs.end(); + } + public: static char ID; PatmosStackCachePromotion(const PatmosTargetMachine &tm): @@ -46,6 +74,11 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return "Patmos StackCache-Promotion pass (machine code)"; } + virtual bool doInitialization(Module &M) override{ + getAnnotatedFunctions(&M); + return false; + } + void processMachineInstruction(MachineInstr& MI); void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; From f3d8fd2e7d49cd27ebc914881a5d75587ecae074 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 16:29:21 +0200 Subject: [PATCH 36/67] add debugs --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index d4167039881d..c2f59e627a46 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -139,13 +139,13 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } - /*for (const auto& store : stores) { - dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"; + for (const auto& store : stores) { + LLVM_DEBUG(dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"); // Trace back to find the AllocaInst if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { - dbgs() << "AI: " << *(AI) << "\n"; + LLVM_DEBUG(dbgs() << "AI: " << *(AI) << "\n"); } - }*/ + } for (const GlobalVariable &GV : M->globals()) { From 48fe7d64ad8a8bcc6c3a87d6fdb2543552a94a01 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 16:33:46 +0200 Subject: [PATCH 37/67] remove external linkage check --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index c2f59e627a46..1cdc96b403f0 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -149,7 +149,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) for (const GlobalVariable &GV : M->globals()) { - if (GV.hasExternalLinkage()) { + //if (GV.hasExternalLinkage()) { if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { return AI == &GV; From c82c2b235ae80623aa8012c91bb7838cc94805f5 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 16:33:57 +0200 Subject: [PATCH 38/67] remove external linkage check --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 1cdc96b403f0..c25da4fea5e4 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -160,7 +160,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) return true; } } - } + //} return false; } From de5dd11216a77a694f2088a0282a47a756ff1230 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 16:38:01 +0200 Subject: [PATCH 39/67] remove annotation check --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index c25da4fea5e4..45ca2546c778 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -222,7 +222,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { + if (EnableStackCachePromotion/* && shouldInstrumentFunc(MF.getFunction())*/) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); From 1ecb90b27f16820dc180c8a424b2c6291b2f7a74 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 17:00:00 +0200 Subject: [PATCH 40/67] add check if depends on global --- .../Target/Patmos/PatmosStackCachePromotion.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 45ca2546c778..0e98b30aaa62 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -182,6 +182,18 @@ bool hasFIonSC(const std::vector deps, return false; } +bool instructionDependsOnGlobal(const MachineInstr &MI) { + for (const MachineOperand &MO : MI.operands()) { + if (MO.isGlobal()) { + const GlobalValue *GV = MO.getGlobal(); + if (isa(GV)) { + return true; + } + } + } + return false; +} + bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { @@ -202,6 +214,10 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew if (Dependencies.size() == 0) return false; + for (const auto& dep : Dependencies) { + if (instructionDependsOnGlobal(*dep)) return false; + } + if (!hasFIonSC(Dependencies, MF)) return false; LLVM_DEBUG(dbgs() << "Updating op...\n"); From d1570fa9ba22e1de36dc0c3f57571d1b66733c1c Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 17:22:51 +0200 Subject: [PATCH 41/67] add check if pointer to FI --- .../Patmos/PatmosStackCachePromotion.cpp | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 0e98b30aaa62..a8e833a6266b 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -147,20 +147,29 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } + if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ + return store->getValueOperand()->getType()->isPointerTy(); + })) { + return true; + } + for (const GlobalVariable &GV : M->globals()) { - //if (GV.hasExternalLinkage()) { - if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ - if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { - return AI == &GV; - } - return false; - })) { - LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); - return true; + if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ + if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { + return AI == &GV; } + return false; + })) { + LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); + return true; } - //} + } + + /*for (const Argument& arg : F.args()) { + + }*/ + return false; } From 6f679edcb2c0574dbec70dfd6d342e2632d6e894 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Thu, 20 Jun 2024 18:11:58 +0200 Subject: [PATCH 42/67] add check if pointer to FI --- .../lib/Target/Patmos/PatmosStackCachePromotion.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index a8e833a6266b..7e0e1d303ea0 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -178,6 +178,7 @@ bool hasFIonSC(const std::vector deps, const MachineFunction &MF) { const PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); + for (const auto MI : deps) { for (const auto &op : MI->operands()) { if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) return false; @@ -191,13 +192,21 @@ bool hasFIonSC(const std::vector deps, return false; } -bool instructionDependsOnGlobal(const MachineInstr &MI) { +bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& MF) { for (const MachineOperand &MO : MI.operands()) { if (MO.isGlobal()) { const GlobalValue *GV = MO.getGlobal(); if (isa(GV)) { return true; } + } else if (MO.isFI()) { + //if (isFIAPointerToExternalSymbol(MO.getIndex(), MF)) return true; + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + const AllocaInst *AI = MFI.getObjectAllocation(MO.getIndex()); + if (!AI && !MFI.isFixedObjectIndex(MO.getIndex())) + return true; + //if (isFIAPointerToExternalSymbol(, MF)) return true; } } return false; @@ -224,7 +233,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew return false; for (const auto& dep : Dependencies) { - if (instructionDependsOnGlobal(*dep)) return false; + if (instructionDependsOnGlobal(*dep, MF)) return false; } if (!hasFIonSC(Dependencies, MF)) From bbc2d83eaeca26e1a685ef3c4943088c015cafaa Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 21 Jun 2024 13:00:25 +0200 Subject: [PATCH 43/67] fix dependency calculation --- .../Target/Patmos/PatmosMachineFunctionInfo.h | 7 +++ .../Patmos/PatmosStackCachePromotion.cpp | 58 +++++++++++-------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosMachineFunctionInfo.h b/llvm/lib/Target/Patmos/PatmosMachineFunctionInfo.h index 9ca564d67f4d..9480c8ed4e44 100644 --- a/llvm/lib/Target/Patmos/PatmosMachineFunctionInfo.h +++ b/llvm/lib/Target/Patmos/PatmosMachineFunctionInfo.h @@ -266,6 +266,13 @@ class PatmosMachineFunctionInfo : public MachineFunctionInfo { return StackCacheAnalysisFIs; } + void removeStackCacheAnalysisFIs(int fi) { + std::vector::iterator position = std::find(StackCacheAnalysisFIs.begin(), StackCacheAnalysisFIs.end(), fi); + + if (position != StackCacheAnalysisFIs.end()) // == myVector.end() means the element was not found + StackCacheAnalysisFIs.erase(position); + } + void addStackCacheAnalysisFI(int fi) { StackCacheAnalysisFIs.push_back(fi); } diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 7e0e1d303ea0..770a06105787 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -58,7 +58,7 @@ void getDeps(MachineInstr* MI, Dependencies.push_back(MI); const MachineRegisterInfo &MRI = MF.getRegInfo(); for (auto &MO : MI->operands()) { - if (MO.isReg() && MO.isUse()) { + if (MO.isReg()) { unsigned Reg = MO.getReg(); if (Register::isVirtualRegister(Reg)) { MachineInstr *DefMI = MRI.getVRegDef(Reg); @@ -72,12 +72,13 @@ void getDeps(MachineInstr* MI, } std::vector getDeps(const MachineInstr &MI, - const MachineFunction &MF) { + const MachineFunction &MF, bool isStore) { const MachineRegisterInfo &MRI = MF.getRegInfo(); std::vector Dependencies; - for (auto &MO : MI.operands()) { - if (MO.isReg() && MO.isUse()) { + for (unsigned i = 0; i < MI.getNumOperands(); ++i) { + auto &MO = MI.getOperand(i); + if (MO.isReg() && (MI.mayStore() ? MO.isUse() && i == 2 : MO.isUse())) { unsigned Reg = MO.getReg(); if (Register::isVirtualRegister(Reg)) { MachineInstr *DefMI = MRI.getVRegDef(Reg); @@ -112,7 +113,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) const MachineFrameInfo &MFI = MF.getFrameInfo(); // Check if the frame index is valid - if (ObjectFI < 0 || ObjectFI >= MFI.getObjectIndexEnd()) { + if (ObjectFI < MFI.getObjectIndexBegin() || ObjectFI >= MFI.getObjectIndexEnd()) { return false; } @@ -175,21 +176,27 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } bool hasFIonSC(const std::vector deps, - const MachineFunction &MF) { - const PatmosMachineFunctionInfo &PMFI = + MachineFunction &MF) { + PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); + bool onSC = false; for (const auto MI : deps) { + LLVM_DEBUG(dbgs() << "Checking MI: " << *MI); for (const auto &op : MI->operands()) { - if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) return false; + if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) { + LLVM_DEBUG(dbgs() << "Removing FI from SC: " << *MI); + PMFI.removeStackCacheAnalysisFIs(op.getIndex()); + return false; + } if (op.isFI() && std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), PMFI.getStackCacheAnalysisFIs().end(), [&op](auto elem) { return elem == op.getIndex(); })) - return true; + onSC |= true; } } - return false; + return onSC; } bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& MF) { @@ -212,7 +219,7 @@ bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& M return false; } -bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, +bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, bool isStore, MachineInstr& MI, MachineFunction &MF) { if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { return false; @@ -221,7 +228,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew if (MI.getOpcode() == OPold) { LLVM_DEBUG(dbgs() << MI); - auto Dependencies = getDeps(MI, MF); + auto Dependencies = getDeps(MI, MF, isStore); LLVM_DEBUG(dbgs() << "\tDepends on: \n"); for (auto &DMI : Dependencies) { @@ -265,26 +272,27 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - // if (!MFI.isFixedObjectIndex(FI) && !isFIusedInCall(MF, FI)) - LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); - PMFI.addStackCacheAnalysisFI(FI); + if (!MFI.isFixedObjectIndex(FI)) { + LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); + PMFI.addStackCacheAnalysisFI(FI); + } } - const std::vector> mappings = { - {Patmos::LWC, Patmos::LWS}, - {Patmos::LHC, Patmos::LHS}, - {Patmos::LBC, Patmos::LBS}, - {Patmos::LHUC, Patmos::LHUS}, - {Patmos::LBUC, Patmos::LBUS}, + const std::vector, unsigned>> mappings = { + {{Patmos::LWC, false}, Patmos::LWS}, + {{Patmos::LHC, false}, Patmos::LHS}, + {{Patmos::LBC, false}, Patmos::LBS}, + {{Patmos::LHUC, false}, Patmos::LHUS}, + {{Patmos::LBUC, false}, Patmos::LBUS}, - {Patmos::SWC, Patmos::SWS}, - {Patmos::SHC, Patmos::SHS}, - {Patmos::SBC, Patmos::SBS}, + {{Patmos::SWC, true}, Patmos::SWS}, + {{Patmos::SHC, true}, Patmos::SHS}, + {{Patmos::SBC, true}, Patmos::SBS}, }; for (auto &BB : MF) { for (auto &MI : BB) { - std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first, elem.second, MI, MF);}); + std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first.first, elem.second, elem.first.second, MI, MF);}); /*replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); replaceOpcodeIfSC(Patmos::LHC, Patmos::LHS, MI, MF); replaceOpcodeIfSC(Patmos::LBC, Patmos::LBS, MI, MF); From b13fc4bf2919e736007c8c379c5d3e8b76ce6b90 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 21 Jun 2024 13:00:38 +0200 Subject: [PATCH 44/67] fix dependency calculation --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index a12600285e39..f7a110dd23d6 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -83,7 +83,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; - bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, + bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, bool isStore, MachineInstr &MI, MachineFunction &MF); }; From 7aaaa24df80951d3af39d43aed79aa0266a9774a Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 21 Jun 2024 13:03:01 +0200 Subject: [PATCH 45/67] cleanup --- .../Patmos/PatmosStackCachePromotion.cpp | 26 +++++++++---------- .../Target/Patmos/PatmosStackCachePromotion.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 770a06105787..62f1502f6a54 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -72,7 +72,7 @@ void getDeps(MachineInstr* MI, } std::vector getDeps(const MachineInstr &MI, - const MachineFunction &MF, bool isStore) { + const MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); std::vector Dependencies; @@ -219,7 +219,7 @@ bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& M return false; } -bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, bool isStore, MachineInstr& MI, +bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { return false; @@ -228,7 +228,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew if (MI.getOpcode() == OPold) { LLVM_DEBUG(dbgs() << MI); - auto Dependencies = getDeps(MI, MF, isStore); + auto Dependencies = getDeps(MI, MF); LLVM_DEBUG(dbgs() << "\tDepends on: \n"); for (auto &DMI : Dependencies) { @@ -278,21 +278,21 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { } } - const std::vector, unsigned>> mappings = { - {{Patmos::LWC, false}, Patmos::LWS}, - {{Patmos::LHC, false}, Patmos::LHS}, - {{Patmos::LBC, false}, Patmos::LBS}, - {{Patmos::LHUC, false}, Patmos::LHUS}, - {{Patmos::LBUC, false}, Patmos::LBUS}, + const std::vector> mappings = { + {Patmos::LWC, Patmos::LWS}, + {Patmos::LHC, Patmos::LHS}, + {Patmos::LBC, Patmos::LBS}, + {Patmos::LHUC, Patmos::LHUS}, + {Patmos::LBUC, Patmos::LBUS}, - {{Patmos::SWC, true}, Patmos::SWS}, - {{Patmos::SHC, true}, Patmos::SHS}, - {{Patmos::SBC, true}, Patmos::SBS}, + {Patmos::SWC, Patmos::SWS}, + {Patmos::SHC, Patmos::SHS}, + {Patmos::SBC, Patmos::SBS}, }; for (auto &BB : MF) { for (auto &MI : BB) { - std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first.first, elem.second, elem.first.second, MI, MF);}); + std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first, elem.second, MI, MF);}); /*replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); replaceOpcodeIfSC(Patmos::LHC, Patmos::LHS, MI, MF); replaceOpcodeIfSC(Patmos::LBC, Patmos::LBS, MI, MF); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index f7a110dd23d6..a12600285e39 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -83,7 +83,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; - bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, bool isStore, + bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, MachineInstr &MI, MachineFunction &MF); }; From 2632b87b63d55ac77c8360ffda14dffde941bd0c Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Sun, 23 Jun 2024 13:15:48 +0200 Subject: [PATCH 46/67] try simplified version of SC optimisation --- .../Patmos/PatmosStackCachePromotion.cpp | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 62f1502f6a54..d47fe3d99486 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -219,6 +219,19 @@ bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& M return false; } +void removeDepFIs(std::vector& deps, MachineFunction &MF) { + PatmosMachineFunctionInfo &PMFI = + *MF.getInfo(); + + for (const auto MI : deps) { + for (const auto &op : MI->operands()) { + if (op.isFI()) { + PMFI.removeStackCacheAnalysisFIs(op.getIndex()); + } + } + } +} + bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, MachineFunction &MF) { if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { @@ -240,11 +253,16 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew return false; for (const auto& dep : Dependencies) { + removeDepFIs(Dependencies, MF); if (instructionDependsOnGlobal(*dep, MF)) return false; } - if (!hasFIonSC(Dependencies, MF)) + if (!hasFIonSC(Dependencies, MF)) { + removeDepFIs(Dependencies, MF); return false; + } + //removeDepFIs(Dependencies, MF); + return true; LLVM_DEBUG(dbgs() << "Updating op...\n"); @@ -308,6 +326,10 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { // Iterate over every Instr x // For each x -> find instrs y that x depends on && transitively // for each y -> if has FI && Is on SC -> convert to L.S/S.S + + for (const int FI : PMFI.getStackCacheAnalysisFIs()) { + LLVM_DEBUG(dbgs() << "FI on Stack Cache: " << FI << "\n"); + } } return true; } From 3031b6b10a1deca2ae1d84d3980a24face3d1cf4 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 13:15:35 +0200 Subject: [PATCH 47/67] try simplified version of SC optimisation --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 4 +++- llvm/lib/Target/Patmos/PatmosStackCachePromotion.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index d47fe3d99486..5a8eef098231 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -281,7 +281,9 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - if (EnableStackCachePromotion/* && shouldInstrumentFunc(MF.getFunction())*/) { + LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " + << MF.getFunction().getName() << "\n"); + if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index a12600285e39..8acd0f9cb8bf 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -57,7 +57,9 @@ class PatmosStackCachePromotion : public MachineFunctionPass { } bool shouldInstrumentFunc(Function &F){ - return annotFuncs.find(&F)!=annotFuncs.end(); + //return F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage(); + return !F.isDeclaration(); + //return annotFuncs.find(&F)!=annotFuncs.end(); } public: From 5c5a45508df049b786a954bd7a6040b04fec0a18 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 13:23:09 +0200 Subject: [PATCH 48/67] try simplified version of SC optimisation --- .../Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- .../Target/Patmos/PatmosStackCachePromotion.h | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 5a8eef098231..5982bc9e1561 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -283,7 +283,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { + if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction()) && !MF.getFunction().getName().startswith("__")) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 8acd0f9cb8bf..ece0252db9f9 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -57,8 +57,22 @@ class PatmosStackCachePromotion : public MachineFunctionPass { } bool shouldInstrumentFunc(Function &F){ + if (F.isDeclaration()) { + return false; + } + + // Check linkage types + if (F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage() || F.hasWeakODRLinkage() || F.hasWeakLinkage()) { + return true; + } + + // External linkage may indicate library functions, but functions in the current compilation unit can also have external linkage + // So we add a module-level check: functions from standard libraries typically reside in modules like "libc" or similar. + // We could additionally use debug information if available, but linkage and definition checks should suffice for most cases. + + return true; //return F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage(); - return !F.isDeclaration(); + //return !F.isDeclaration(); //return annotFuncs.find(&F)!=annotFuncs.end(); } From 7a222d5908930ac40d6a78b4b7804f1a07e4aadd Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 13:44:31 +0200 Subject: [PATCH 49/67] improve library check for sco pass --- .../Patmos/PatmosStackCachePromotion.cpp | 2 +- .../Target/Patmos/PatmosStackCachePromotion.h | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 5982bc9e1561..5a8eef098231 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -283,7 +283,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction()) && !MF.getFunction().getName().startswith("__")) { + if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index ece0252db9f9..63ed37f21d18 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -66,10 +66,24 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return true; } - // External linkage may indicate library functions, but functions in the current compilation unit can also have external linkage - // So we add a module-level check: functions from standard libraries typically reside in modules like "libc" or similar. - // We could additionally use debug information if available, but linkage and definition checks should suffice for most cases. + // Additional module-level checks + const Module *M = F.getParent(); + if (M) { + // Optionally check the module name to see if it matches common library patterns + // Example: Functions from standard libraries often have specific module identifiers + StringRef ModuleIdentifier = M->getModuleIdentifier(); + if (ModuleIdentifier.endswith(".so") || ModuleIdentifier.endswith(".a") || ModuleIdentifier.contains("lib")) { + return false; + } + + // Additional heuristic: Check for specific function names that are commonly found in libraries + StringRef FunctionName = F.getName(); + if (FunctionName.startswith("_Z") || FunctionName.startswith("__") || FunctionName.startswith("llvm.")) { + return false; + } + } + // By default, assume the function is defined in the current compilation unit return true; //return F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage(); //return !F.isDeclaration(); From 151588186580f26c5e2617bb935c508939fa0392 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 13:48:13 +0200 Subject: [PATCH 50/67] improve library check for sco pass --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 63ed37f21d18..cb1846c4a366 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -66,6 +66,12 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return true; } + // Additional heuristic: Check for specific function names that are commonly found in libraries + StringRef FunctionName = F.getName(); + if (FunctionName.startswith("_Z") || FunctionName.startswith("__") || FunctionName.startswith("llvm.")) { + return false; + } + // Additional module-level checks const Module *M = F.getParent(); if (M) { @@ -75,12 +81,6 @@ class PatmosStackCachePromotion : public MachineFunctionPass { if (ModuleIdentifier.endswith(".so") || ModuleIdentifier.endswith(".a") || ModuleIdentifier.contains("lib")) { return false; } - - // Additional heuristic: Check for specific function names that are commonly found in libraries - StringRef FunctionName = F.getName(); - if (FunctionName.startswith("_Z") || FunctionName.startswith("__") || FunctionName.startswith("llvm.")) { - return false; - } } // By default, assume the function is defined in the current compilation unit From 5f1d39c35ad61a729e6b69bc44bd6aec1d60f5e1 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 13:51:36 +0200 Subject: [PATCH 51/67] fix library check for sco pass --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 2 +- llvm/lib/Target/Patmos/PatmosStackCachePromotion.h | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 5a8eef098231..5982bc9e1561 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -283,7 +283,7 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction())) { + if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction()) && !MF.getFunction().getName().startswith("__")) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index cb1846c4a366..0f78ebbc2b25 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -61,11 +61,6 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return false; } - // Check linkage types - if (F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage() || F.hasWeakODRLinkage() || F.hasWeakLinkage()) { - return true; - } - // Additional heuristic: Check for specific function names that are commonly found in libraries StringRef FunctionName = F.getName(); if (FunctionName.startswith("_Z") || FunctionName.startswith("__") || FunctionName.startswith("llvm.")) { From 02106d651da7d0e352026e287e9d1e64ade8b162 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 14:58:19 +0200 Subject: [PATCH 52/67] remove logs --- .../Patmos/PatmosStackCachePromotion.cpp | 57 +++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 5982bc9e1561..e6ae03e22493 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -123,7 +123,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); - LLVM_DEBUG(dbgs() << "AllocaInst: " << *AI << "\n"); + //LLVM_DEBUG(dbgs() << "AllocaInst: " << *AI << "\n"); const Function &F = MF.getFunction(); const Module *M = F.getParent(); @@ -140,13 +140,13 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } - for (const auto& store : stores) { + /*for (const auto& store : stores) { LLVM_DEBUG(dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"); // Trace back to find the AllocaInst if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { LLVM_DEBUG(dbgs() << "AI: " << *(AI) << "\n"); } - } + }*/ if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ return store->getValueOperand()->getType()->isPointerTy(); @@ -162,7 +162,7 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } return false; })) { - LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); + //LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); return true; } } @@ -182,7 +182,7 @@ bool hasFIonSC(const std::vector deps, bool onSC = false; for (const auto MI : deps) { - LLVM_DEBUG(dbgs() << "Checking MI: " << *MI); + //LLVM_DEBUG(dbgs() << "Checking MI: " << *MI); for (const auto &op : MI->operands()) { if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) { LLVM_DEBUG(dbgs() << "Removing FI from SC: " << *MI); @@ -239,15 +239,15 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew } if (MI.getOpcode() == OPold) { - LLVM_DEBUG(dbgs() << MI); + //LLVM_DEBUG(dbgs() << MI); auto Dependencies = getDeps(MI, MF); - LLVM_DEBUG(dbgs() << "\tDepends on: \n"); + /*LLVM_DEBUG(dbgs() << "\tDepends on: \n"); for (auto &DMI : Dependencies) { LLVM_DEBUG(dbgs() << "\t" << *DMI); } - LLVM_DEBUG(dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "\n");*/ if (Dependencies.size() == 0) return false; @@ -279,11 +279,46 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew return false; } +void printFIInfo(MachineFunction& MF, int FI) { + MachineFrameInfo &MFI = MF.getFrameInfo(); + + if (MFI.isFixedObjectIndex(FI)) { + errs() << "Frame index " << FI << " is a fixed-sized object.\n"; + } + if (MFI.isVariableSizedObjectIndex(FI)) { + errs() << "Frame index " << FI << " is a variable-sized object.\n"; + } + if (MFI.isSpillSlotObjectIndex(FI)) { + errs() << "Frame index " << FI << " is a spill slot object.\n"; + } + if (MFI.isDeadObjectIndex(FI)) { + errs() << "Frame index " << FI << " is a dead object.\n"; + } + if (MFI.isAliasedObjectIndex(FI)) { + errs() << "Frame index " << FI << " is an aliased object.\n"; + } + if (MFI.isStatepointSpillSlotObjectIndex(FI)) { + errs() << "Frame index " << FI << " is a statepoint spill slot object.\n"; + } + if (MFI.isImmutableObjectIndex(FI)) { + errs() << "Frame index " << FI << " is an immutable ObjectIndex.\n"; + } + if (MFI.isObjectPreAllocated(FI)) { + errs() << "Frame index " << FI << " is pre allocated.\n"; + } + if (MFI.isObjectSExt(FI)) { + errs() << "Frame index " << FI << " is ObjectSExt.\n"; + } + if (MFI.isObjectZExt(FI)) { + errs() << "Frame index " << FI << " is ObjectZExt.\n"; + } +} + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - if (EnableStackCachePromotion && shouldInstrumentFunc(MF.getFunction()) && !MF.getFunction().getName().startswith("__")) { + if (EnableStackCachePromotion /*&& shouldInstrumentFunc(MF.getFunction())*/) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); @@ -292,7 +327,9 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - if (!MFI.isFixedObjectIndex(FI)) { + printFIInfo(MF, FI); + + if (!MFI.isFixedObjectIndex(FI) && !MFI.isVariableSizedObjectIndex(FI)) { LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); PMFI.addStackCacheAnalysisFI(FI); } From c74633046ed27927d105f605a6314fd130386e77 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 15:03:07 +0200 Subject: [PATCH 53/67] add aliased object check --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index e6ae03e22493..2477ddff58d9 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -316,8 +316,8 @@ void printFIInfo(MachineFunction& MF, int FI) { bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " - << MF.getFunction().getName() << "\n"); + /*LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " + << MF.getFunction().getName() << "\n");*/ if (EnableStackCachePromotion /*&& shouldInstrumentFunc(MF.getFunction())*/) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); @@ -329,7 +329,7 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { printFIInfo(MF, FI); - if (!MFI.isFixedObjectIndex(FI) && !MFI.isVariableSizedObjectIndex(FI)) { + if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI)) { LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); PMFI.addStackCacheAnalysisFI(FI); } From 523fcc161b9f013d925b5a60619337e0b30d8616 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 15:40:29 +0200 Subject: [PATCH 54/67] add minimal functional version --- .../Patmos/PatmosStackCachePromotion.cpp | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 2477ddff58d9..bdf79dcf4fda 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -185,7 +185,7 @@ bool hasFIonSC(const std::vector deps, //LLVM_DEBUG(dbgs() << "Checking MI: " << *MI); for (const auto &op : MI->operands()) { if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) { - LLVM_DEBUG(dbgs() << "Removing FI from SC: " << *MI); + LLVM_DEBUG(dbgs() << "Removing FI from SC: " << op.getIndex()); PMFI.removeStackCacheAnalysisFIs(op.getIndex()); return false; } @@ -314,6 +314,22 @@ void printFIInfo(MachineFunction& MF, int FI) { } } +bool isFrameIndexUsedAsPointer(MachineFunction &MF, int FI) { + for (MachineFunction::iterator MBB = MF.begin(), MBBE = MF.end(); MBB != MBBE; ++MBB) { + for (MachineBasicBlock::iterator MI = MBB->begin(), MIE = MBB->end(); MI != MIE; ++MI) { + for (unsigned i = 0; i < MI->getNumOperands(); ++i) { + MachineOperand &MO = MI->getOperand(i); + if (MO.isFI() && MO.getIndex() == FI) { + // Check if the instruction uses the frame index as a pointer + if (MI->mayLoad() || MI->mayStore()) { + return true; + } + } + } + } + } + return false; +} bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { /*LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " @@ -327,15 +343,15 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - printFIInfo(MF, FI); + //printFIInfo(MF, FI); - if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI)) { + if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer(MF, FI)) { LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); PMFI.addStackCacheAnalysisFI(FI); } } - const std::vector> mappings = { + /*const std::vector> mappings = { {Patmos::LWC, Patmos::LWS}, {Patmos::LHC, Patmos::LHS}, {Patmos::LBC, Patmos::LBS}, @@ -350,24 +366,15 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { for (auto &BB : MF) { for (auto &MI : BB) { std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first, elem.second, MI, MF);}); - /*replaceOpcodeIfSC(Patmos::LWC, Patmos::LWS, MI, MF); - replaceOpcodeIfSC(Patmos::LHC, Patmos::LHS, MI, MF); - replaceOpcodeIfSC(Patmos::LBC, Patmos::LBS, MI, MF); - replaceOpcodeIfSC(Patmos::LHUC, Patmos::LHUS, MI, MF); - replaceOpcodeIfSC(Patmos::LBUC, Patmos::LBUS, MI, MF); - - replaceOpcodeIfSC(Patmos::SWC, Patmos::SWS, MI, MF); - replaceOpcodeIfSC(Patmos::SHC, Patmos::SHS, MI, MF); - replaceOpcodeIfSC(Patmos::SBC, Patmos::SBS, MI, MF);*/ } - } + }*/ // Iterate over every Instr x // For each x -> find instrs y that x depends on && transitively // for each y -> if has FI && Is on SC -> convert to L.S/S.S for (const int FI : PMFI.getStackCacheAnalysisFIs()) { - LLVM_DEBUG(dbgs() << "FI on Stack Cache: " << FI << "\n"); + dbgs() << "FI on Stack Cache: " << FI << "\n"; } } return true; From 24e9b5c48a7f4a0ebf16775309b02dfef0ba863f Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 16:03:36 +0200 Subject: [PATCH 55/67] finish minimal functional version --- .../Patmos/PatmosStackCachePromotion.cpp | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index bdf79dcf4fda..d4b54ba5ed81 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -17,6 +17,8 @@ #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/IR/InstIterator.h" +#include using namespace llvm; @@ -331,6 +333,60 @@ bool isFrameIndexUsedAsPointer(MachineFunction &MF, int FI) { return false; } +void collectPointerUses(const Value *V, std::unordered_set &Visited) { + for (const User *U : V->users()) { + if (const Instruction *Inst = dyn_cast(U)) { + if (Visited.insert(Inst).second) { + // Recursively track uses through bitcasts, phis, selects, etc. + if (isa(Inst) || isa(Inst) || isa(Inst)) { + collectPointerUses(Inst, Visited); + } else if (isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) { + Visited.insert(Inst); + } + } + } + } +} + +bool isAllocaUsedAsPointer(const AllocaInst *AI) { + std::unordered_set Visited; + collectPointerUses(AI, Visited); + + for (const Instruction *Inst : Visited) { + if (/*isa(Inst) || isa(Inst) || */isa(Inst) || isa(Inst)) { + return true; + } + } + return false; +} + +bool isFrameIndexUsedAsPointer2(MachineFunction &MF, int ObjectFI) { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + + // Check if the frame index is valid + if (ObjectFI < MFI.getObjectIndexBegin() || ObjectFI >= MFI.getObjectIndexEnd()) { + return true; + } + + const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); + if (!AI) return true; + + //const Function &F = MF.getFunction(); + return isAllocaUsedAsPointer(AI); + + /*for (const BasicBlock &BB : F) { + for (const Instruction &I : BB) { + if (const auto *gep = dyn_cast(&I)) { + if (gep->getPointerOperand() == AI) { + return true; + } + } + } + }*/ + + return false; +} + bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { /*LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " << MF.getFunction().getName() << "\n");*/ @@ -345,7 +401,7 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { //printFIInfo(MF, FI); - if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer(MF, FI)) { + if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer2(MF, FI)) { LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); PMFI.addStackCacheAnalysisFI(FI); } From c270025f1a54390eba07b696f9f6aa5585b1a419 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 16:25:04 +0200 Subject: [PATCH 56/67] cleanup --- .../Patmos/PatmosStackCachePromotion.cpp | 114 ++---------------- 1 file changed, 8 insertions(+), 106 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index d4b54ba5ed81..18bb745e4c36 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -35,23 +35,6 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } -bool isFIusedInCall(MachineFunction &MF, unsigned FI) { - for (const auto &MBB : MF) { - for (const auto &MI : MBB) { - if (MI.isCall()) { - for (const MachineOperand &MO : MI.operands()) { - if (MO.isFI()) { - int FrameIndex = MO.getIndex(); - if (FrameIndex == FI) - return true; - } - } - } - } - } - return false; -} - void getDeps(MachineInstr* MI, const MachineFunction &MF, std::vector& Dependencies) { @@ -142,14 +125,6 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } - /*for (const auto& store : stores) { - LLVM_DEBUG(dbgs() << "Store VO: " << *(store->getValueOperand()) << "\n"); - // Trace back to find the AllocaInst - if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { - LLVM_DEBUG(dbgs() << "AI: " << *(AI) << "\n"); - } - }*/ - if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ return store->getValueOperand()->getType()->isPointerTy(); })) { @@ -169,11 +144,6 @@ bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) } } - /*for (const Argument& arg : F.args()) { - - }*/ - - return false; } @@ -281,58 +251,6 @@ bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew return false; } -void printFIInfo(MachineFunction& MF, int FI) { - MachineFrameInfo &MFI = MF.getFrameInfo(); - - if (MFI.isFixedObjectIndex(FI)) { - errs() << "Frame index " << FI << " is a fixed-sized object.\n"; - } - if (MFI.isVariableSizedObjectIndex(FI)) { - errs() << "Frame index " << FI << " is a variable-sized object.\n"; - } - if (MFI.isSpillSlotObjectIndex(FI)) { - errs() << "Frame index " << FI << " is a spill slot object.\n"; - } - if (MFI.isDeadObjectIndex(FI)) { - errs() << "Frame index " << FI << " is a dead object.\n"; - } - if (MFI.isAliasedObjectIndex(FI)) { - errs() << "Frame index " << FI << " is an aliased object.\n"; - } - if (MFI.isStatepointSpillSlotObjectIndex(FI)) { - errs() << "Frame index " << FI << " is a statepoint spill slot object.\n"; - } - if (MFI.isImmutableObjectIndex(FI)) { - errs() << "Frame index " << FI << " is an immutable ObjectIndex.\n"; - } - if (MFI.isObjectPreAllocated(FI)) { - errs() << "Frame index " << FI << " is pre allocated.\n"; - } - if (MFI.isObjectSExt(FI)) { - errs() << "Frame index " << FI << " is ObjectSExt.\n"; - } - if (MFI.isObjectZExt(FI)) { - errs() << "Frame index " << FI << " is ObjectZExt.\n"; - } -} - -bool isFrameIndexUsedAsPointer(MachineFunction &MF, int FI) { - for (MachineFunction::iterator MBB = MF.begin(), MBBE = MF.end(); MBB != MBBE; ++MBB) { - for (MachineBasicBlock::iterator MI = MBB->begin(), MIE = MBB->end(); MI != MIE; ++MI) { - for (unsigned i = 0; i < MI->getNumOperands(); ++i) { - MachineOperand &MO = MI->getOperand(i); - if (MO.isFI() && MO.getIndex() == FI) { - // Check if the instruction uses the frame index as a pointer - if (MI->mayLoad() || MI->mayStore()) { - return true; - } - } - } - } - } - return false; -} - void collectPointerUses(const Value *V, std::unordered_set &Visited) { for (const User *U : V->users()) { if (const Instruction *Inst = dyn_cast(U)) { @@ -353,14 +271,14 @@ bool isAllocaUsedAsPointer(const AllocaInst *AI) { collectPointerUses(AI, Visited); for (const Instruction *Inst : Visited) { - if (/*isa(Inst) || isa(Inst) || */isa(Inst) || isa(Inst)) { + if (isa(Inst) || isa(Inst)) { return true; } } return false; } -bool isFrameIndexUsedAsPointer2(MachineFunction &MF, int ObjectFI) { +bool isFrameIndexUsedAsPointer(MachineFunction &MF, int ObjectFI) { const MachineFrameInfo &MFI = MF.getFrameInfo(); // Check if the frame index is valid @@ -371,39 +289,23 @@ bool isFrameIndexUsedAsPointer2(MachineFunction &MF, int ObjectFI) { const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); if (!AI) return true; - //const Function &F = MF.getFunction(); return isAllocaUsedAsPointer(AI); - - /*for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) { - if (const auto *gep = dyn_cast(&I)) { - if (gep->getPointerOperand() == AI) { - return true; - } - } - } - }*/ - - return false; } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { - /*LLVM_DEBUG(dbgs() << "Checking Stack Cache promotion for: " - << MF.getFunction().getName() << "\n");*/ - if (EnableStackCachePromotion /*&& shouldInstrumentFunc(MF.getFunction())*/) { + if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " << MF.getFunction().getName() << "\n"); - // Calculate the amount of bytes to store on SC MachineFrameInfo &MFI = MF.getFrameInfo(); PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); + std::unordered_set stillPossibleFIs; for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - //printFIInfo(MF, FI); - - if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer2(MF, FI)) { - LLVM_DEBUG(dbgs() << "Adding FI to Stack Cache: " << FI << "\n"); + if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer(MF, FI)) { PMFI.addStackCacheAnalysisFI(FI); + } else { + stillPossibleFIs.insert(FI); } } @@ -430,7 +332,7 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { // for each y -> if has FI && Is on SC -> convert to L.S/S.S for (const int FI : PMFI.getStackCacheAnalysisFIs()) { - dbgs() << "FI on Stack Cache: " << FI << "\n"; + LLVM_DEBUG(dbgs() << "FI on Stack Cache: " << FI << "\n"); } } return true; From b07ce9410e739410b9217ca5127e5dc7d2c30591 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Mon, 24 Jun 2024 21:22:45 +0200 Subject: [PATCH 57/67] cleanup --- .../Patmos/PatmosStackCachePromotion.cpp | 347 ++++++------------ .../Target/Patmos/PatmosStackCachePromotion.h | 62 ---- 2 files changed, 111 insertions(+), 298 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 18bb745e4c36..505062ee6f34 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -18,6 +18,8 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/IR/InstIterator.h" +#include +#include #include using namespace llvm; @@ -26,6 +28,10 @@ static cl::opt EnableStackCachePromotion( "mpatmos-enable-stack-cache-promotion", cl::init(false), cl::desc("Enable the compiler to promote data to the stack cache")); +static cl::opt EnableArrayStackCachePromotion( + "mpatmos-enable-array-stack-cache-promotion", cl::init(false), + cl::desc("Enable the compiler to promote arrays to the stack cache")); + char PatmosStackCachePromotion::ID = 0; /// createDataCacheAccessEliminationPass - Returns a new @@ -35,261 +41,113 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } -void getDeps(MachineInstr* MI, - const MachineFunction &MF, - std::vector& Dependencies) { - if (std::find(Dependencies.begin(), Dependencies.end(), MI) != Dependencies.end()) - return; - Dependencies.push_back(MI); - const MachineRegisterInfo &MRI = MF.getRegInfo(); - for (auto &MO : MI->operands()) { - if (MO.isReg()) { - unsigned Reg = MO.getReg(); - if (Register::isVirtualRegister(Reg)) { - MachineInstr *DefMI = MRI.getVRegDef(Reg); - if (DefMI) { - getDeps(DefMI, MF, Dependencies); - } - } - } - } - return; -} -std::vector getDeps(const MachineInstr &MI, - const MachineFunction &MF) { - const MachineRegisterInfo &MRI = MF.getRegInfo(); - std::vector Dependencies; - - for (unsigned i = 0; i < MI.getNumOperands(); ++i) { - auto &MO = MI.getOperand(i); - if (MO.isReg() && (MI.mayStore() ? MO.isUse() && i == 2 : MO.isUse())) { - unsigned Reg = MO.getReg(); - if (Register::isVirtualRegister(Reg)) { - MachineInstr *DefMI = MRI.getVRegDef(Reg); - if (DefMI) { - getDeps(DefMI, MF, Dependencies); +void collectPointerUses(const Value *V, std::unordered_set &Visited) { + for (const User *U : V->users()) { + if (const Instruction *Inst = dyn_cast(U)) { + if (Visited.insert(Inst).second) { + // Recursively track uses through bitcasts, phis, selects, etc. + if (isa(Inst) || isa(Inst) || isa(Inst)) { + collectPointerUses(Inst, Visited); + } else if (isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) { + Visited.insert(Inst); } } } } - return Dependencies; } -const GlobalVariable* findGlobalVariable(const Value *V) { - if (auto *AI = dyn_cast(V)) - return AI; - - if (auto *BCI = dyn_cast(V)) - return findGlobalVariable(BCI->getOperand(0)); - if (auto *GEP = dyn_cast(V)) - return findGlobalVariable(GEP->getPointerOperand()); - if (auto *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast) { - return findGlobalVariable(CE->getOperand(0)); +bool isAllocaUsedAsPointer(const AllocaInst *AI) { + std::unordered_set Visited; + collectPointerUses(AI, Visited); + + for (const Instruction *Inst : Visited) { + if (isa(Inst) || isa(Inst)) { + return true; } } - - return nullptr; + return false; } -bool isFIAPointerToExternalSymbol(const int ObjectFI, const MachineFunction &MF) { - // Get the frame information from the machine function +bool isFrameIndexUsedAsPointer(MachineFunction &MF, int ObjectFI) { const MachineFrameInfo &MFI = MF.getFrameInfo(); // Check if the frame index is valid if (ObjectFI < MFI.getObjectIndexBegin() || ObjectFI >= MFI.getObjectIndexEnd()) { - return false; - } - - // Check if the frame index is associated with a fixed object - if (MFI.isFixedObjectIndex(ObjectFI)) { - return false; + return true; } const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); - //LLVM_DEBUG(dbgs() << "AllocaInst: " << *AI << "\n"); + if (!AI) return true; - const Function &F = MF.getFunction(); - const Module *M = F.getParent(); + return isAllocaUsedAsPointer(AI); +} + +bool isIndirectUseRecursive(MachineInstr &MI, MachineRegisterInfo &MRI, int FI, SmallPtrSetImpl &Visited) { + if (Visited.count(&MI)) + return false; + Visited.insert(&MI); - std::vector stores; + for (auto &MO : MI.operands()) { + if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) { // TODO Check this + MachineInstr *DefMI = MRI.getVRegDef(MO.getReg()); + if (!DefMI) + continue; - for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) { - if (const auto *store = dyn_cast(&I)) { - if (store->getPointerOperand() == AI) { - stores.push_back(store); + for (auto &DefMO : DefMI->operands()) { + if (DefMO.isFI() && DefMO.getIndex() == FI) { + return true; } } - } - } - - if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ - return store->getValueOperand()->getType()->isPointerTy(); - })) { - return true; - } - - for (const GlobalVariable &GV : M->globals()) { - if (std::any_of(stores.begin(), stores.end(), [&](const StoreInst* store){ - if (const GlobalVariable *AI = findGlobalVariable(store->getValueOperand())) { - return AI == &GV; + if (isIndirectUseRecursive(*DefMI, MRI, FI, Visited)) { + return true; } - return false; - })) { - //LLVM_DEBUG(dbgs() << "store from: " << GV << "\n"); - return true; } } return false; } -bool hasFIonSC(const std::vector deps, - MachineFunction &MF) { - PatmosMachineFunctionInfo &PMFI = - *MF.getInfo(); - - bool onSC = false; - for (const auto MI : deps) { - //LLVM_DEBUG(dbgs() << "Checking MI: " << *MI); - for (const auto &op : MI->operands()) { - if (op.isFI() && isFIAPointerToExternalSymbol(op.getIndex(), MF)) { - LLVM_DEBUG(dbgs() << "Removing FI from SC: " << op.getIndex()); - PMFI.removeStackCacheAnalysisFIs(op.getIndex()); - return false; - } - if (op.isFI() && - std::any_of(PMFI.getStackCacheAnalysisFIs().begin(), - PMFI.getStackCacheAnalysisFIs().end(), - [&op](auto elem) { return elem == op.getIndex(); })) - onSC |= true; - } - } - return onSC; -} - -bool instructionDependsOnGlobal(const MachineInstr &MI, const MachineFunction& MF) { - for (const MachineOperand &MO : MI.operands()) { - if (MO.isGlobal()) { - const GlobalValue *GV = MO.getGlobal(); - if (isa(GV)) { - return true; - } - } else if (MO.isFI()) { - //if (isFIAPointerToExternalSymbol(MO.getIndex(), MF)) return true; - const MachineFrameInfo &MFI = MF.getFrameInfo(); +bool isFrameIndexUsedIndirectly(MachineInstr &MI, MachineRegisterInfo &MRI, int FI) { + // Check if the instruction is a memory load/store + if (!MI.mayLoad() && !MI.mayStore()) + return false; - const AllocaInst *AI = MFI.getObjectAllocation(MO.getIndex()); - if (!AI && !MFI.isFixedObjectIndex(MO.getIndex())) - return true; - //if (isFIAPointerToExternalSymbol(, MF)) return true; + SmallPtrSet Visited; + for (auto &MO : MI.operands()) { + if (MO.isReg() && isIndirectUseRecursive(MI, MRI, FI, Visited)) { + return true; } } - return false; -} -void removeDepFIs(std::vector& deps, MachineFunction &MF) { - PatmosMachineFunctionInfo &PMFI = - *MF.getInfo(); - - for (const auto MI : deps) { - for (const auto &op : MI->operands()) { - if (op.isFI()) { - PMFI.removeStackCacheAnalysisFIs(op.getIndex()); - } - } - } + return false; } -bool PatmosStackCachePromotion::replaceOpcodeIfSC(unsigned OPold, unsigned OPnew, MachineInstr& MI, - MachineFunction &MF) { - if (std::any_of(MI.operands_begin(), MI.operands_end(), [](auto element){return element.isFI();})) { - return false; - } - - if (MI.getOpcode() == OPold) { - //LLVM_DEBUG(dbgs() << MI); - - auto Dependencies = getDeps(MI, MF); - - /*LLVM_DEBUG(dbgs() << "\tDepends on: \n"); - for (auto &DMI : Dependencies) { - LLVM_DEBUG(dbgs() << "\t" << *DMI); - } - LLVM_DEBUG(dbgs() << "\n");*/ - - if (Dependencies.size() == 0) - return false; - - for (const auto& dep : Dependencies) { - removeDepFIs(Dependencies, MF); - if (instructionDependsOnGlobal(*dep, MF)) return false; - } - - if (!hasFIonSC(Dependencies, MF)) { - removeDepFIs(Dependencies, MF); - return false; - } - //removeDepFIs(Dependencies, MF); - return true; - LLVM_DEBUG(dbgs() << "Updating op...\n"); +std::unordered_set findIndirectUses(MachineFunction &MF, int FI) { + MachineRegisterInfo &MRI = MF.getRegInfo(); - /*LLVM_DEBUG(dbgs() << "\tDepends on: \n"); - for (auto &DMI : Dependencies) { - LLVM_DEBUG(dbgs() << *DMI); - } - LLVM_DEBUG(dbgs() << "\n"); - LLVM_DEBUG(dbgs() << "\n");*/ - - MI.setDesc(TII->get(OPnew)); - return true; - } - return false; -} - -void collectPointerUses(const Value *V, std::unordered_set &Visited) { - for (const User *U : V->users()) { - if (const Instruction *Inst = dyn_cast(U)) { - if (Visited.insert(Inst).second) { - // Recursively track uses through bitcasts, phis, selects, etc. - if (isa(Inst) || isa(Inst) || isa(Inst)) { - collectPointerUses(Inst, Visited); - } else if (isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) { - Visited.insert(Inst); - } + std::unordered_set IndirectUses; + for (auto &MBB : MF) { + for (auto &MI : MBB) { + if (std::any_of(MI.operands_begin(), MI.operands_end(), [](const MachineOperand& op){ + return op.isFI(); + })) + continue; + if (isFrameIndexUsedIndirectly(MI, MRI, FI)) { + IndirectUses.insert(&MI); } } } -} - -bool isAllocaUsedAsPointer(const AllocaInst *AI) { - std::unordered_set Visited; - collectPointerUses(AI, Visited); - for (const Instruction *Inst : Visited) { - if (isa(Inst) || isa(Inst)) { - return true; + // For demonstration purposes, print the indirect uses found + LLVM_DEBUG({ + for (MachineInstr *MI : IndirectUses) { + dbgs() << "Indirect use of frame index " << FI << ": " << *MI; } - } - return false; -} - -bool isFrameIndexUsedAsPointer(MachineFunction &MF, int ObjectFI) { - const MachineFrameInfo &MFI = MF.getFrameInfo(); - - // Check if the frame index is valid - if (ObjectFI < MFI.getObjectIndexBegin() || ObjectFI >= MFI.getObjectIndexEnd()) { - return true; - } - - const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); - if (!AI) return true; - - return isAllocaUsedAsPointer(AI); + }); + return IndirectUses; } bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { @@ -300,36 +158,53 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo &MFI = MF.getFrameInfo(); PatmosMachineFunctionInfo &PMFI = *MF.getInfo(); - std::unordered_set stillPossibleFIs; + std::unordered_set StillPossibleFIs; for (unsigned FI = 0, FIe = MFI.getObjectIndexEnd(); FI != FIe; FI++) { - if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI) && !isFrameIndexUsedAsPointer(MF, FI)) { - PMFI.addStackCacheAnalysisFI(FI); - } else { - stillPossibleFIs.insert(FI); + if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI)) { + if (!isFrameIndexUsedAsPointer(MF, FI)) { + PMFI.addStackCacheAnalysisFI(FI); + } else { + StillPossibleFIs.insert(FI); + } } } - /*const std::vector> mappings = { - {Patmos::LWC, Patmos::LWS}, - {Patmos::LHC, Patmos::LHS}, - {Patmos::LBC, Patmos::LBS}, - {Patmos::LHUC, Patmos::LHUS}, - {Patmos::LBUC, Patmos::LBUS}, - - {Patmos::SWC, Patmos::SWS}, - {Patmos::SHC, Patmos::SHS}, - {Patmos::SBC, Patmos::SBS}, - }; - - for (auto &BB : MF) { - for (auto &MI : BB) { - std::any_of(mappings.begin(), mappings.end(), [&MI, &MF, this](auto elem){return replaceOpcodeIfSC(elem.first, elem.second, MI, MF);}); - } - }*/ + if (EnableArrayStackCachePromotion) { + + // Logic for handling arrays on SC + const std::unordered_map Mappings = { + {Patmos::LWC, Patmos::LWS}, {Patmos::LHC, Patmos::LHS}, + {Patmos::LBC, Patmos::LBS}, {Patmos::LHUC, Patmos::LHUS}, + {Patmos::LBUC, Patmos::LBUS}, + + {Patmos::SWC, Patmos::SWS}, {Patmos::SHC, Patmos::SHS}, + {Patmos::SBC, Patmos::SBS}, + }; - // Iterate over every Instr x - // For each x -> find instrs y that x depends on && transitively - // for each y -> if has FI && Is on SC -> convert to L.S/S.S + for (const auto FI : StillPossibleFIs) { + const auto &Uses = findIndirectUses(MF, FI); + + const bool AllConvertible = std::all_of( + Uses.begin(), Uses.end(), [&Mappings](MachineInstr *Inst) { + return Mappings.find(Inst->getOpcode()) != Mappings.end(); + }); + + if (AllConvertible) { + LLVM_DEBUG(dbgs() << "All instructions referencing FI: " << FI + << " are convertible" + << "\n"); + + // Put FI on SC + PMFI.addStackCacheAnalysisFI(FI); + + // Now convert all instructions + for (MachineInstr *Use : Uses) { + const unsigned OPnew = Mappings.at(Use->getOpcode()); + Use->setDesc(TII->get(OPnew)); + } + } + } + } for (const int FI : PMFI.getStackCacheAnalysisFIs()) { LLVM_DEBUG(dbgs() << "FI on Stack Cache: " << FI << "\n"); diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h index 0f78ebbc2b25..799378c03257 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.h @@ -32,58 +32,6 @@ class PatmosStackCachePromotion : public MachineFunctionPass { const PatmosInstrInfo *TII; const PatmosRegisterInfo *TRI; - std::set annotFuncs; - - void getAnnotatedFunctions(Module *M){ - for (Module::global_iterator I = M->global_begin(), - E = M->global_end(); - I != E; - ++I) { - - if (I->getName() == "llvm.global.annotations") { - ConstantArray *CA = dyn_cast(I->getOperand(0)); - for(auto OI = CA->op_begin(); OI != CA->op_end(); ++OI){ - ConstantStruct *CS = dyn_cast(OI->get()); - Function *FUNC = dyn_cast(CS->getOperand(0)->getOperand(0)); - GlobalVariable *AnnotationGL = dyn_cast(CS->getOperand(1)->getOperand(0)); - StringRef annotation = dyn_cast(AnnotationGL->getInitializer())->getAsCString(); - if(annotation.compare("stack_cache")==0){ - annotFuncs.insert(FUNC); - errs() << "Found annotated function " << FUNC->getName()<<"\n"; - } - } - } - } - } - - bool shouldInstrumentFunc(Function &F){ - if (F.isDeclaration()) { - return false; - } - - // Additional heuristic: Check for specific function names that are commonly found in libraries - StringRef FunctionName = F.getName(); - if (FunctionName.startswith("_Z") || FunctionName.startswith("__") || FunctionName.startswith("llvm.")) { - return false; - } - - // Additional module-level checks - const Module *M = F.getParent(); - if (M) { - // Optionally check the module name to see if it matches common library patterns - // Example: Functions from standard libraries often have specific module identifiers - StringRef ModuleIdentifier = M->getModuleIdentifier(); - if (ModuleIdentifier.endswith(".so") || ModuleIdentifier.endswith(".a") || ModuleIdentifier.contains("lib")) { - return false; - } - } - - // By default, assume the function is defined in the current compilation unit - return true; - //return F.hasInternalLinkage() || F.hasPrivateLinkage() || F.hasLinkOnceODRLinkage() || F.hasLinkOnceLinkage(); - //return !F.isDeclaration(); - //return annotFuncs.find(&F)!=annotFuncs.end(); - } public: static char ID; @@ -99,17 +47,7 @@ class PatmosStackCachePromotion : public MachineFunctionPass { return "Patmos StackCache-Promotion pass (machine code)"; } - virtual bool doInitialization(Module &M) override{ - getAnnotatedFunctions(&M); - return false; - } - - void processMachineInstruction(MachineInstr& MI); - void calcOffsets(MachineFunction& MF); bool runOnMachineFunction(MachineFunction &MF) override ; - - bool replaceOpcodeIfSC(unsigned int OPold, unsigned int OPnew, - MachineInstr &MI, MachineFunction &MF); }; } // End llvm namespace From a2571dd46011f8314a961e33300174da6f08d053 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Fri, 28 Jun 2024 13:31:29 +0200 Subject: [PATCH 58/67] disable call check for inline assembly --- .../Patmos/PatmosStackCachePromotion.cpp | 2 +- .../Patmos/assembly/instructions/lws.ll | 26 +++++++------------ .../Patmos/programs/bounded/assert_correct.py | 3 ++- .../bounded/single_source/stackcache/array.ll | 2 ++ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 505062ee6f34..9472edc665f6 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -62,7 +62,7 @@ bool isAllocaUsedAsPointer(const AllocaInst *AI) { collectPointerUses(AI, Visited); for (const Instruction *Inst : Visited) { - if (isa(Inst) || isa(Inst)) { + if (isa(Inst) || (isa(Inst) && !(dyn_cast(Inst)->isInlineAsm()))) { return true; } } diff --git a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll index a5fe883dd917..9e1886d4d44b 100644 --- a/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll +++ b/llvm/test/CodeGen/Patmos/assembly/instructions/lws.ll @@ -3,23 +3,17 @@ define i32 @main() { entry: - %stack_var = alloca [2 x i32] - %stack_var_1 = getelementptr [2 x i32], [2 x i32]* %stack_var, i32 0, i32 0 - store i32 15, i32* %stack_var_1 - %stack_var_2 = getelementptr [2 x i32], [2 x i32]* %stack_var, i32 0, i32 1 - store i32 16, i32* %stack_var_2 - - %asm_result = call { i32, i32 } asm " - lws $0 = [$2] - lws $1 = [$2 + 1] - nop - ", "=&r,=r,r" - (i32* %stack_var_1) - + %stack_var = alloca i32, align 4 + store i32 15, i32* %stack_var, align 4 + %stack_var_2 = alloca i32, align 4 + store i32 16, i32* %stack_var_2, align 4 + ; Extract results - %result_1 = extractvalue { i32, i32 } %asm_result, 0 - %result_2 = extractvalue { i32, i32 } %asm_result, 1 - + %result_1 = call i32 asm "lws $0 = [$1]", "=r,r" (i32* %stack_var) + %result_2 = call i32 asm "lws $0 = [$1] + nop", "=r,r" (i32* %stack_var_2) + + ; Check correctness %correct_1 = icmp eq i32 %result_1, 15 %correct_2 = icmp eq i32 %result_2, 16 diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py index 38c598a07893..b63395df98de 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py +++ b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py @@ -250,7 +250,8 @@ def compile_and_test_matrix(llc_args, pasim_args, matrix): "-O2 --mpatmos-max-subfunction-size=64", [ "", - "--mpatmos-enable-stack-cache-promotion" + "--mpatmos-enable-stack-cache-promotion", + ["--mpatmos-enable-array-stack-cache-promotion"] ], [ # We add this indirection so that commenting out the following line will remove all traditional tests diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll index 45fabd1150cf..fc787e30a58d 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll +++ b/llvm/test/CodeGen/Patmos/programs/bounded/single_source/stackcache/array.ll @@ -28,6 +28,7 @@ entry: for.cond: ; preds = %for.inc, %entry %1 = load i32, i32* %i, align 4 %cmp = icmp ult i32 %1, 3 + call void @llvm.loop.bound(i32 0, i32 3) br i1 %cmp, label %for.body, label %for.end for.body: ; preds = %for.cond @@ -59,6 +60,7 @@ for.end: ; preds = %for.cond ; Function Attrs: argmemonly nofree nosync nounwind willreturn declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i32, i1 immarg) #1 +declare void @llvm.loop.bound(i32, i32) attributes #0 = { noinline nounwind optnone "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { argmemonly nofree nosync nounwind willreturn } From 6bf7e1fa64b2631c1933b0bc1ec23476ed6f8826 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 16 Jul 2024 08:24:02 +0200 Subject: [PATCH 59/67] trigger ci --- llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index 9472edc665f6..dde235043e1f 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -170,7 +170,6 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { } if (EnableArrayStackCachePromotion) { - // Logic for handling arrays on SC const std::unordered_map Mappings = { {Patmos::LWC, Patmos::LWS}, {Patmos::LHC, Patmos::LHS}, From e95c194aa17057e84d1931e0c5dd89d489e3faf3 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 10 Sep 2024 12:47:21 +0200 Subject: [PATCH 60/67] add arm64 mac target support --- llvm/cmake/platforms/Patmos.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/cmake/platforms/Patmos.cmake b/llvm/cmake/platforms/Patmos.cmake index 8ea9de12d711..15b8b6662e53 100644 --- a/llvm/cmake/platforms/Patmos.cmake +++ b/llvm/cmake/platforms/Patmos.cmake @@ -6,6 +6,8 @@ if (${DUMP_MACHINE} MATCHES "x86_64-linux-gnu") set( TARGET_TRIPLE "x86_64-linux-gnu") elseif(${DUMP_MACHINE} MATCHES "x86_64-apple-darwin.*") set( TARGET_TRIPLE "x86_64-apple-darwin") +elseif(${DUMP_MACHINE} MATCHES "arm64-apple-darwin.*") + set( TARGET_TRIPLE "arm64-apple-darwin") else() message(FATAL_ERROR "Unsupported platform for packaging") endif() From 0e54d779fd5fe54d09963d19a0009bf2fbbc0cf7 Mon Sep 17 00:00:00 2001 From: Daniel Seifert <11018429+R3freshReload@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:55:31 +0200 Subject: [PATCH 61/67] add texinfo to test for pipeline error --- .github/actions/install-dependencies/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index 221867273dac..4acfb351e97f 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -8,7 +8,7 @@ runs: name: Install GNU-tar as 'tar' shell: bash run: | - brew install gnu-tar + brew install gnu-tar texinfo # Set gtar to be available as 'tar' echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH - name: Create Installation Directory From fae93a53192bbbd152302ed4c436117756715b77 Mon Sep 17 00:00:00 2001 From: Daniel Seifert <11018429+R3freshReload@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:38:49 +0200 Subject: [PATCH 62/67] change CI newlib to fork to test for mac error --- .github/actions/build-test-all/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/build-test-all/action.yml b/.github/actions/build-test-all/action.yml index b4665caeacbc..18fbdeab1505 100644 --- a/.github/actions/build-test-all/action.yml +++ b/.github/actions/build-test-all/action.yml @@ -167,10 +167,10 @@ runs: - name: Download Newlib if: inputs.enable-package == 'true' env: - NEWLIB_COMMIT: 4a74fe0ca51e6f462999446f8adbfd8f6b8c91e5 + NEWLIB_COMMIT: 79b0b16dfc224c2d63b31e5c314bc2a5c430f01e shell: bash run: | - git clone https://github.com/t-crest/patmos-newlib ${{env.NEWLIB_PATH}} + git clone https://github.com/R3freshReload/patmos-newlib.git ${{env.NEWLIB_PATH}} cd ${{env.NEWLIB_PATH}} git checkout $NEWLIB_COMMIT # Builds newlib to Patmos assembly (instead of bitcode) From 4eccd6ab5383680d7be175af89b5e4becfef1e46 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Wed, 11 Sep 2024 12:40:58 +0200 Subject: [PATCH 63/67] add additional mac targets to ci --- .github/workflows/patmos-ci.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/patmos-ci.yml b/.github/workflows/patmos-ci.yml index eb56b6059ce9..0c63dd733794 100644 --- a/.github/workflows/patmos-ci.yml +++ b/.github/workflows/patmos-ci.yml @@ -69,10 +69,16 @@ jobs: - platform: ubuntu-20.04 cc: gcc cxx: g++ - - platform: macos-latest + - platform: macos-latest # ARM cc: clang cxx: clang++ - - platform: macos-12 + - platform: macos-14 # ARM + cc: clang + cxx: clang++ + - platform: macos-13 # x86 + cc: clang + cxx: clang++ + - platform: macos-12 # x86 cc: clang cxx: clang++ @@ -105,10 +111,16 @@ jobs: - platform: ubuntu-20.04 cc: gcc cxx: g++ - - platform: macos-latest + - platform: macos-latest # ARM cc: clang cxx: clang++ - - platform: macos-12 + - platform: macos-14 # ARM + cc: clang + cxx: clang++ + - platform: macos-13 # x86 + cc: clang + cxx: clang++ + - platform: macos-12 # x86 cc: clang cxx: clang++ needs: [package-patmos] From 8991041631bc565188b9056fa046a2ce5f2fcbb8 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Tue, 15 Oct 2024 16:26:30 +0200 Subject: [PATCH 64/67] add simple working solution for array opt --- .../Patmos/PatmosStackCachePromotion.cpp | 210 +++++++++--------- 1 file changed, 111 insertions(+), 99 deletions(-) diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index dde235043e1f..ed88e3779f81 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -41,115 +41,122 @@ llvm::createPatmosStackCachePromotionPass(const PatmosTargetMachine &tm) { return new PatmosStackCachePromotion(tm); } - -void collectPointerUses(const Value *V, std::unordered_set &Visited) { - for (const User *U : V->users()) { - if (const Instruction *Inst = dyn_cast(U)) { - if (Visited.insert(Inst).second) { - // Recursively track uses through bitcasts, phis, selects, etc. - if (isa(Inst) || isa(Inst) || isa(Inst)) { - collectPointerUses(Inst, Visited); - } else if (isa(Inst) || isa(Inst) || isa(Inst) || isa(Inst)) { - Visited.insert(Inst); +namespace { + void collectPointerUses(const Value *V, + std::unordered_set &Visited) { + for (const User *U : V->users()) { + if (const Instruction *Inst = dyn_cast(U)) { + if (Visited.insert(Inst).second) { + // Recursively track uses through bitcasts, phis, selects, etc. + if (isa(Inst) || isa(Inst) || + isa(Inst)) { + collectPointerUses(Inst, Visited); + } else if (isa(Inst) || isa(Inst) || + isa(Inst) || isa(Inst)) { + Visited.insert(Inst); + } } } } } -} -bool isAllocaUsedAsPointer(const AllocaInst *AI) { - std::unordered_set Visited; - collectPointerUses(AI, Visited); + bool isAllocaUsedAsPointer(const AllocaInst *AI) { + std::unordered_set Visited; + collectPointerUses(AI, Visited); - for (const Instruction *Inst : Visited) { - if (isa(Inst) || (isa(Inst) && !(dyn_cast(Inst)->isInlineAsm()))) { - return true; + for (const Instruction *Inst : Visited) { + if (isa(Inst) || + (isa(Inst) && !(dyn_cast(Inst)->isInlineAsm()))) { + return true; + } } + return false; } - return false; -} -bool isFrameIndexUsedAsPointer(MachineFunction &MF, int ObjectFI) { - const MachineFrameInfo &MFI = MF.getFrameInfo(); + bool isFrameIndexUsedAsPointer(MachineFunction &MF, int ObjectFI) { + const MachineFrameInfo &MFI = MF.getFrameInfo(); - // Check if the frame index is valid - if (ObjectFI < MFI.getObjectIndexBegin() || ObjectFI >= MFI.getObjectIndexEnd()) { - return true; - } + // Check if the frame index is valid + if (ObjectFI < MFI.getObjectIndexBegin() || + ObjectFI >= MFI.getObjectIndexEnd()) { + return true; + } - const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); - if (!AI) return true; + const AllocaInst *AI = MFI.getObjectAllocation(ObjectFI); + if (!AI) + return true; - return isAllocaUsedAsPointer(AI); -} + return isAllocaUsedAsPointer(AI); + } -bool isIndirectUseRecursive(MachineInstr &MI, MachineRegisterInfo &MRI, int FI, SmallPtrSetImpl &Visited) { - if (Visited.count(&MI)) - return false; - Visited.insert(&MI); + bool isIndirectUseRecursive(MachineInstr &MI, MachineRegisterInfo &MRI, int FI, + std::set &Visited) { + if (Visited.count(&MI)) + return false; + Visited.insert(&MI); + + for (auto &MO : + MI.uses()) { // We only care about the registers this instruction uses + if (MO.isReg() && + Register::isVirtualRegister(MO.getReg())) { // TODO Check this + MachineInstr *DefMI = MRI.getVRegDef(MO.getReg()); + if (!DefMI) { + dbgs() << "VRegister was never defined???\n"; + continue; + } - for (auto &MO : MI.operands()) { - if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) { // TODO Check this - MachineInstr *DefMI = MRI.getVRegDef(MO.getReg()); - if (!DefMI) - continue; + for (auto &DefMO : DefMI->operands()) { + if (DefMO.isFI() && DefMO.getIndex() == FI) { + return true; + } + } - for (auto &DefMO : DefMI->operands()) { - if (DefMO.isFI() && DefMO.getIndex() == FI) { + if (isIndirectUseRecursive(*DefMI, MRI, FI, Visited)) { return true; } } - - if (isIndirectUseRecursive(*DefMI, MRI, FI, Visited)) { - return true; - } } - } - - return false; -} -bool isFrameIndexUsedIndirectly(MachineInstr &MI, MachineRegisterInfo &MRI, int FI) { - // Check if the instruction is a memory load/store - if (!MI.mayLoad() && !MI.mayStore()) return false; - - SmallPtrSet Visited; - for (auto &MO : MI.operands()) { - if (MO.isReg() && isIndirectUseRecursive(MI, MRI, FI, Visited)) { - return true; - } } - return false; -} - - -std::unordered_set findIndirectUses(MachineFunction &MF, int FI) { - MachineRegisterInfo &MRI = MF.getRegInfo(); + // Check if the FI is used in the instruction or in any of its dependant instructions + bool isFrameIndexUsedIndirectly(MachineInstr &MI, MachineRegisterInfo &MRI, + int FI) { + // We dont need to check MI since this function should not be called if MI already uses FI - std::unordered_set IndirectUses; - for (auto &MBB : MF) { - for (auto &MI : MBB) { - if (std::any_of(MI.operands_begin(), MI.operands_end(), [](const MachineOperand& op){ - return op.isFI(); - })) - continue; - if (isFrameIndexUsedIndirectly(MI, MRI, FI)) { - IndirectUses.insert(&MI); - } - } + std::set Visited; + // Then we track all the dependant instructions for each of the operands + return isIndirectUseRecursive(MI, MRI, FI, Visited); } - // For demonstration purposes, print the indirect uses found - LLVM_DEBUG({ - for (MachineInstr *MI : IndirectUses) { - dbgs() << "Indirect use of frame index " << FI << ": " << *MI; + std::unordered_set findIndirectUses(MachineFunction &MF, + int FI) { + MachineRegisterInfo &MRI = MF.getRegInfo(); + + std::unordered_set IndirectUses; + for (auto &MBB : MF) { + for (auto &MI : MBB) { + if (std::any_of(MI.operands_begin(), MI.operands_end(), + [FI](const MachineOperand &op) { + return op.isFI() && op.getIndex() == FI; + })) + continue; // Dont need to check direct accesses as they are automatically converted during frame lowering + if (isFrameIndexUsedIndirectly(MI, MRI, FI)) { + IndirectUses.insert(&MI); + } + } } - }); - return IndirectUses; -} + // For demonstration purposes, print the indirect uses found + LLVM_DEBUG({ + for (MachineInstr *MI : IndirectUses) { + dbgs() << "Indirect use of frame index " << FI << ": " << *MI; + } + }); + return IndirectUses; + } +} // namespace bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (EnableStackCachePromotion) { LLVM_DEBUG(dbgs() << "Enabled Stack Cache promotion for: " @@ -182,26 +189,31 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { for (const auto FI : StillPossibleFIs) { const auto &Uses = findIndirectUses(MF, FI); - - const bool AllConvertible = std::all_of( - Uses.begin(), Uses.end(), [&Mappings](MachineInstr *Inst) { - return Mappings.find(Inst->getOpcode()) != Mappings.end(); - }); - - if (AllConvertible) { - LLVM_DEBUG(dbgs() << "All instructions referencing FI: " << FI - << " are convertible" - << "\n"); - - // Put FI on SC + if (Uses.empty()) { PMFI.addStackCacheAnalysisFI(FI); - - // Now convert all instructions - for (MachineInstr *Use : Uses) { - const unsigned OPnew = Mappings.at(Use->getOpcode()); - Use->setDesc(TII->get(OPnew)); + dbgs() << "NO Indirect uses found for FI: " << FI << "\n"; + } /*else { + + const bool AllConvertible = std::all_of( + Uses.begin(), Uses.end(), [&Mappings](MachineInstr *Inst) { + return Mappings.find(Inst->getOpcode()) != Mappings.end(); + }); + + if (AllConvertible) { + dbgs() << "All instructions referencing FI: " << FI + << " are convertible" + << "\n"; + + // Put FI on SC + PMFI.addStackCacheAnalysisFI(FI); + + // Now convert all instructions + for (MachineInstr *Use : Uses) { + const unsigned OPnew = Mappings.at(Use->getOpcode()); + Use->setDesc(TII->get(OPnew)); + } } - } + }*/ } } From 54a24ba85f9ff4992b2f1b6fd626c7bbac5ab679 Mon Sep 17 00:00:00 2001 From: Johannes Gernedl Date: Fri, 15 Nov 2024 12:07:16 +0100 Subject: [PATCH 65/67] Update test cases to check everything except singlepath with stach-cache-promotion enabled --- .../Patmos/programs/bounded/assert_correct.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py index b63395df98de..8bfe7744eaad 100644 --- a/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py +++ b/llvm/test/CodeGen/Patmos/programs/bounded/assert_correct.py @@ -251,17 +251,17 @@ def compile_and_test_matrix(llc_args, pasim_args, matrix): [ "", "--mpatmos-enable-stack-cache-promotion", - ["--mpatmos-enable-array-stack-cache-promotion"] - ], - [ - # We add this indirection so that commenting out the following line will remove all traditional tests - "", + "--mpatmos-enable-stack-cache-promotion --mpatmos-enable-array-stack-cache-promotion", [ - #Traditional + # We add this indirection so that commenting out the following line will remove all traditional tests "", - # Traditional code with PML output, just to make sure we can - # output it without errors. Testing the output is not done. - "-mpatmos-serialize=" + compiled + ".pml -mpatmos-serialize-functions=" + sp_root + [ + #Traditional + "", + # Traditional code with PML output, just to make sure we can + # output it without errors. Testing the output is not done. + "-mpatmos-serialize=" + compiled + ".pml -mpatmos-serialize-functions=" + sp_root + ] ] ], [ From 6469be52eaf369da866dd12acd7c945362f48209 Mon Sep 17 00:00:00 2001 From: Emad Jacob Maroun Date: Wed, 15 Jan 2025 14:12:09 +0100 Subject: [PATCH 66/67] Fix PML output --- llvm/lib/Target/Patmos/PMLExport.cpp | 27 +++++++++---------- llvm/lib/Target/Patmos/PatmosExport.cpp | 2 +- .../Patmos/PatmosStackCachePromotion.cpp | 9 ++++++- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Patmos/PMLExport.cpp b/llvm/lib/Target/Patmos/PMLExport.cpp index 0bc94ccdaefa..54136449c688 100644 --- a/llvm/lib/Target/Patmos/PMLExport.cpp +++ b/llvm/lib/Target/Patmos/PMLExport.cpp @@ -61,7 +61,7 @@ template <> struct FlowGraphTrait { return llvm::succ_end(BB); } static StringValue getName(const BasicBlock *BB) { - return BB->getName().str(); + return BB->getNameOrAsOperand(); } }; template <> struct FlowGraphTrait { @@ -221,10 +221,10 @@ yaml::FlowFact *PMLBitcodeExport::createLoopFact(const BasicB auto *FF = new yaml::FlowFact(yaml::level_bitcode); - FF->setLoopScope(Fn->getName().str(), BB->getName().str()); + FF->setLoopScope(Fn->getName().str(), BB->getNameOrAsOperand()); yaml::ProgramPoint *Block = - yaml::ProgramPoint::CreateBlock(Fn->getName().str(), BB->getName().str()); + yaml::ProgramPoint::CreateBlock(Fn->getName().str(), BB->getNameOrAsOperand()); FF->addTermLHS(Block, 1LL); FF->RHS = RHS; @@ -247,27 +247,24 @@ void PMLBitcodeExport::serialize(MachineFunction &MF) yaml::BitcodeFunction *F = new yaml::BitcodeFunction(Fn.getName().str()); F->Level = yaml::level_bitcode; yaml::BitcodeBlock *B; - for (Function::const_iterator BI = Fn.begin(), BE = Fn.end(); BI != BE; + for (auto BI = Fn.begin(), BE = Fn.end(); BI != BE; ++BI) { - if (BI->getName().empty()) { - llvm::errs() << "warning: unnamed bit-code BB in PML export\n"; - } - B = F->addBlock(new yaml::BitcodeBlock(BI->getName().str())); + B = F->addBlock(new yaml::BitcodeBlock(BI->getNameOrAsOperand())); Loop *Loop = LI.getLoopFor(&*BI); while (Loop) { - B->Loops.push_back(Loop->getHeader()->getName().str()); + B->Loops.push_back(Loop->getHeader()->getNameOrAsOperand()); Loop = Loop->getParentLoop(); } /// B->MapsTo = (maybe C-source debug info?) - for (const_pred_iterator PI = pred_begin(&*BI), PE = pred_end(&*BI); + for (auto PI = pred_begin(&*BI), PE = pred_end(&*BI); PI != PE; ++PI) { - B->Predecessors.push_back((*PI)->getName().str()); + B->Predecessors.push_back((*PI)->getNameOrAsOperand()); } for (auto SI = succ_begin(&*BI), SE = succ_end(&*BI); SI != SE; ++SI) { - B->Successors.push_back((*SI)->getName().str()); + B->Successors.push_back((*SI)->getNameOrAsOperand()); } unsigned Index = 0; @@ -849,7 +846,7 @@ void addProgressNodes(yaml::RelationGraph *RG, } else { RN = RG->addNode(yaml::rnt_progress); - RN->setSrcBlock(IQI->first->getName().str()); + RN->setSrcBlock(IQI->first->getNameOrAsOperand()); RN->setDstBlock(MQI->first->getNumber()); RMap.insert(std::make_pair(PNID, RN)); RTodo.push_back(std::make_pair(PNID, RN)); @@ -935,7 +932,7 @@ void PMLRelationGraphExport::serialize(MachineFunction &MF) auto *SrcScope = new yaml::RelationScope( BF.getName().str(), yaml::level_bitcode); RG = new yaml::RelationGraph(SrcScope, DstScope); - RG->getEntryNode()->setSrcBlock(BF.getEntryBlock().getName().str()); + RG->getEntryNode()->setSrcBlock(BF.getEntryBlock().getNameOrAsOperand()); RG->getEntryNode()->setDstBlock(MF.front().getNumber()); UnmatchedEvents.clear(); @@ -974,7 +971,7 @@ void PMLRelationGraphExport::serialize(MachineFunction &MF) // MBB, resp.), which results in new src/dst nodes being created, and // two bitcode and machinecode-level maps from events to a list of // (bitcode/machine block, list of RG predecessor blocks) pairs - expandProgressNode(RG, RN, yaml::rnt_src, [](auto *node, auto* block){node->setSrcBlock(block->getName().str());}, IBB, IEventMap, IEvents); + expandProgressNode(RG, RN, yaml::rnt_src, [](auto *node, auto* block){node->setSrcBlock(block->getNameOrAsOperand());}, IBB, IEventMap, IEvents); expandProgressNode(RG, RN, yaml::rnt_dst, [](auto *node, auto* block){node->setDstBlock(block->getNumber());}, MBB, MEventMap, MEvents); // For each event and corresponding bitcode list IList and machinecode diff --git a/llvm/lib/Target/Patmos/PatmosExport.cpp b/llvm/lib/Target/Patmos/PatmosExport.cpp index f60cf4207111..82835d54f4d9 100644 --- a/llvm/lib/Target/Patmos/PatmosExport.cpp +++ b/llvm/lib/Target/Patmos/PatmosExport.cpp @@ -367,7 +367,7 @@ namespace llvm { // FIXME // we don't add it immediately to PMF, as we only support // arguments in registers at this point - std::string ArgName = ("%" + I->getName()).str(); + std::string ArgName = I->getNameOrAsOperand(); yaml::Argument *Arg = new yaml::Argument(ArgName, FAIdx); bool allInRegs = true; diff --git a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp index ed88e3779f81..72685c8fa5fa 100644 --- a/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp +++ b/llvm/lib/Target/Patmos/PatmosStackCachePromotion.cpp @@ -24,6 +24,11 @@ using namespace llvm; +#define DEBUG_TYPE "patmos" + +STATISTIC(StackPromoLocValues, "Number of local variables promoted to the stack cache"); +STATISTIC(StackPromoArrays, "Number of Arrays promoted to the stack cache"); + static cl::opt EnableStackCachePromotion( "mpatmos-enable-stack-cache-promotion", cl::init(false), cl::desc("Enable the compiler to promote data to the stack cache")); @@ -170,6 +175,7 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { if (!MFI.isFixedObjectIndex(FI) && MFI.isAliasedObjectIndex(FI)) { if (!isFrameIndexUsedAsPointer(MF, FI)) { PMFI.addStackCacheAnalysisFI(FI); + StackPromoLocValues++; } else { StillPossibleFIs.insert(FI); } @@ -191,7 +197,8 @@ bool PatmosStackCachePromotion::runOnMachineFunction(MachineFunction &MF) { const auto &Uses = findIndirectUses(MF, FI); if (Uses.empty()) { PMFI.addStackCacheAnalysisFI(FI); - dbgs() << "NO Indirect uses found for FI: " << FI << "\n"; + StackPromoArrays++; + LLVM_DEBUG(dbgs() << "NO Indirect uses found for FI: " << FI << "\n"); } /*else { const bool AllConvertible = std::all_of( From 3fba0c484a3b418d831e0b504a819bad4ccf3548 Mon Sep 17 00:00:00 2001 From: Emad Jacob Maroun Date: Wed, 15 Jan 2025 14:45:24 +0100 Subject: [PATCH 67/67] temp fixes --- llvm/include/llvm/Support/Signals.h | 2 ++ llvm/lib/Target/Patmos/PatmosInstrInfo.cpp | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h index 44f5a750ff5c..2810713fd2aa 100644 --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -15,6 +15,8 @@ #define LLVM_SUPPORT_SIGNALS_H #include +#include + namespace llvm { class StringRef; diff --git a/llvm/lib/Target/Patmos/PatmosInstrInfo.cpp b/llvm/lib/Target/Patmos/PatmosInstrInfo.cpp index 13c4627df593..b7f4f5b553ff 100644 --- a/llvm/lib/Target/Patmos/PatmosInstrInfo.cpp +++ b/llvm/lib/Target/Patmos/PatmosInstrInfo.cpp @@ -575,7 +575,6 @@ PatmosII::MemType PatmosInstrInfo::getMemType(const MachineInstr &MI) { case SWM: case SHM: case SBM: return PatmosII::MEM_M; default: - MI.dump(); llvm_unreachable("Unexpected memory access instruction!"); }