Skip to content

[SandboxVec] Optimization remarks #129582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions llvm/include/llvm/SandboxIR/Pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace llvm {
class AAResults;
class ScalarEvolution;
class TargetTransformInfo;
class OptimizationRemarkEmitter;

namespace sandboxir {

Expand All @@ -27,17 +28,20 @@ class Analyses {
AAResults *AA = nullptr;
ScalarEvolution *SE = nullptr;
TargetTransformInfo *TTI = nullptr;
OptimizationRemarkEmitter *ORE = nullptr;

Analyses() = default;

public:
Analyses(AAResults &AA, ScalarEvolution &SE, TargetTransformInfo &TTI)
: AA(&AA), SE(&SE), TTI(&TTI) {}
Analyses(AAResults &AA, ScalarEvolution &SE, TargetTransformInfo &TTI,
OptimizationRemarkEmitter &ORE)
: AA(&AA), SE(&SE), TTI(&TTI), ORE(&ORE) {}

public:
AAResults &getAA() const { return *AA; }
ScalarEvolution &getScalarEvolution() const { return *SE; }
TargetTransformInfo &getTTI() const { return *TTI; }
OptimizationRemarkEmitter &getORE() const { return *ORE; }
/// For use by unit tests.
static Analyses emptyForTesting() { return Analyses(); }
};
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/SandboxIR/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Verifier.h"
#include "llvm/SandboxIR/Function.h"
#include "llvm/SandboxIR/Instruction.h"
Expand Down Expand Up @@ -131,6 +132,15 @@ class Utils {
const auto &LLVMF = *cast<llvm::Function>(F->Val);
return llvm::verifyFunction(LLVMF, &OS);
}

/// Returns an optimization remark for \p I's location.
// TODO: OptimizationRemark can leak llvm IR through getRegion().
static OptimizationRemark getOptimizationRemark(const char *PassName,
StringRef RemarkName,
Instruction *I) {
return OptimizationRemark(PassName, RemarkName,
cast<llvm::Instruction>(I->Val));
}
};

} // namespace llvm::sandboxir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "sandbox-vectorizer"
#define PASS_NAME "sandbox-vectorizer"
#define DEBUG_TYPE PASS_NAME
#define DEBUG_PREFIX "SBVec: "

#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEBUG_H
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <memory>

#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/PassManager.h"
#include "llvm/SandboxIR/Context.h"
Expand All @@ -24,6 +25,7 @@ class SandboxVectorizerPass : public PassInfoMixin<SandboxVectorizerPass> {
TargetTransformInfo *TTI = nullptr;
AAResults *AA = nullptr;
ScalarEvolution *SE = nullptr;
OptimizationRemarkEmitter *ORE = nullptr;
// NOTE: We define the Context as a pass-scope object instead of local object
// in runOnFunction() because the passes defined in the pass-manager need
// access to it for registering/deregistering callbacks during construction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/SandboxIR/Utils.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InstructionCost.h"
#include "llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h"
Expand All @@ -29,9 +31,13 @@ bool TransactionAcceptOrRevert::runOnRegion(Region &Rgn, const Analyses &A) {
<< CostAfter << "/" << CostThreshold << ")\n");
// TODO: Print costs / write to remarks.
auto &Tracker = Rgn.getContext().getTracker();
if (CostAfterMinusBefore < -CostThreshold) {
if (!Rgn.empty() && CostAfterMinusBefore < -CostThreshold) {
bool HasChanges = !Tracker.empty();
Tracker.accept();
// TODO: Use a more accurate debug location than Rgn.begin().
A.getORE().emit(
Utils::getOptimizationRemark(PASS_NAME, "Vectorized", *Rgn.begin())
<< "Vectorized with cost " << ore::NV("Cost", CostAfterMinusBefore));
LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "*** Transaction Accept ***\n");
return HasChanges;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ PreservedAnalyses SandboxVectorizerPass::run(Function &F,
TTI = &AM.getResult<TargetIRAnalysis>(F);
AA = &AM.getResult<AAManager>(F);
SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
ORE = &AM.getResult<OptimizationRemarkEmitterAnalysis>(F);

bool Changed = runImpl(F);
if (!Changed)
Expand Down Expand Up @@ -132,7 +133,7 @@ bool SandboxVectorizerPass::runImpl(Function &LLVMF) {

// Create SandboxIR for LLVMF and run BottomUpVec on it.
sandboxir::Function &F = *Ctx->createFunction(&LLVMF);
sandboxir::Analyses A(*AA, *SE, *TTI);
sandboxir::Analyses A(*AA, *SE, *TTI, *ORE);
bool Change = FPM.runOnFunction(F, A);
// Given that sandboxir::Context `Ctx` is defined at a pass-level scope, the
// maps from LLVM IR to Sandbox IR may go stale as later passes remove LLVM IR
Expand Down
31 changes: 31 additions & 0 deletions llvm/test/Transforms/SandboxVectorizer/remarks.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -pass-remarks-output=%t < %s | FileCheck %s
; RUN: FileCheck --input-file=%t --check-prefix=REMARKS %s

; REMARKS-LABEL: --- !Passed
; REMARKS-LABEL: Pass: sandbox-vectorizer
; REMARKS-LABEL: Name: Vectorized
; REMARKS-LABEL: Function: remarks1
; REMARKS-LABEL: Args:
; REMARKS-LABEL: - String: 'Vectorized with cost '
; REMARKS-LABEL: - Cost: '-3'

define void @remarks1(ptr %ptr) {
; CHECK-LABEL: define void @remarks1(
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META0:![0-9]+]]
; CHECK-NEXT: store <2 x float> [[VECL]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
; CHECK-NEXT: ret void
;
%ptr0 = getelementptr float, ptr %ptr, i32 0
%ptr1 = getelementptr float, ptr %ptr, i32 1
%ld0 = load float, ptr %ptr0
%ld1 = load float, ptr %ptr1
store float %ld0, ptr %ptr0
store float %ld1, ptr %ptr1
ret void
}
;.
; CHECK: [[META0]] = distinct !{!"sandboxregion"}
;.
50 changes: 50 additions & 0 deletions llvm/test/Transforms/SandboxVectorizer/remarks_not_vectorized.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=sandbox-vectorizer -sbvec-cost-threshold=-9999 -sbvec-vec-reg-bits=1024 -pass-remarks-output=%t < %s | FileCheck %s
; RUN: FileCheck --allow-empty --input-file=%t --check-prefix=REMARKS %s

; REMARKS-NOT: .*

; Check that we don't get any remarks when the code isn't vectorized
; but the threshold allows it.
define void @no_remarks1(ptr %ptr) {
; CHECK-LABEL: define void @no_remarks1(
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 42
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: store float [[LD0]], ptr [[PTR0]], align 4
; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
; CHECK-NEXT: ret void
;
%ptr0 = getelementptr float, ptr %ptr, i32 0
%ptr1 = getelementptr float, ptr %ptr, i32 42
%ld0 = load float, ptr %ptr0
%ld1 = load float, ptr %ptr1
store float %ld0, ptr %ptr0
store float %ld1, ptr %ptr1
ret void
}

; Same but doesn't get vectorized because of scheduling.
define void @no_remarks2(ptr %ptr, ptr %ptrX) {
; CHECK-LABEL: define void @no_remarks2(
; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
; CHECK-NEXT: [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
; CHECK-NEXT: store float [[LD0]], ptr [[PTR0]], align 4
; CHECK-NEXT: store float 0.000000e+00, ptr [[PTRX]], align 4
; CHECK-NEXT: store float [[LD1]], ptr [[PTR1]], align 4
; CHECK-NEXT: ret void
;
%ptr0 = getelementptr float, ptr %ptr, i32 0
%ptr1 = getelementptr float, ptr %ptr, i32 1
%ld0 = load float, ptr %ptr0
%ld1 = load float, ptr %ptr1
store float %ld0, ptr %ptr0
store float 0.0, ptr %ptrX
store float %ld1, ptr %ptr1
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ define void @foo() {
AM.registerPass([] { return AssumptionAnalysis(); });
AM.registerPass([] { return DominatorTreeAnalysis(); });
AM.registerPass([] { return LoopAnalysis(); });
AM.registerPass([] { return OptimizationRemarkEmitterAnalysis(); });
SVecPass.run(LLVMF, AM);
// This shouldn't crash.
SVecPass.run(LLVMF, AM);
Expand Down