Skip to content

Commit a3ae0dd

Browse files
authored
[InferAddressSpaces] Add InferAddressSpaces pass to pipeline for SPIR (#7418)
Clang generates 'addrspacecast' instructions to align address spaces between alloca/global variables/kernel parameters and flat address space pointers (i.e. addrspace(4)). For the SPIR/SPIR-V target, addrspace(4) is the generic address space and these addrspacecast instructions can be safely removed from the code when named address space can be deduced. To perform this removing, the InferAddressSpaces pass has been added to the clang optimization pipeline for SPIR and SPIR-V targets. This pass should be run after the other optimization passes (both function and module) and, it is very important, after inlining to let the pass "understand" from which address space as many as possible variables came and eliminate as many as possible addrspacecast instructions. The elimination of redundant addrspacecast instruction decreases the size of the generated SPIR-V module and therefore makes less pressure on the backend/JIT compilers.
1 parent cd832bf commit a3ae0dd

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===---- SPIR.h - Declare SPIR and SPIR-V target interfaces ----*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
namespace clang {
12+
namespace targets {
13+
14+
// Used by both the SPIR and SPIR-V targets. Code of the generic address space
15+
// for the target
16+
constexpr unsigned SPIR_GENERIC_AS = 4u;
17+
18+
} // namespace targets
19+
} // namespace clang

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "clang/Basic/Diagnostic.h"
1212
#include "clang/Basic/LangOptions.h"
1313
#include "clang/Basic/TargetOptions.h"
14+
#include "clang/Basic/Targets/SPIR.h"
1415
#include "clang/Frontend/FrontendDiagnostic.h"
1516
#include "clang/Frontend/Utils.h"
1617
#include "clang/Lex/HeaderSearchOptions.h"
@@ -87,6 +88,7 @@
8788
#include "llvm/Transforms/Scalar.h"
8889
#include "llvm/Transforms/Scalar/EarlyCSE.h"
8990
#include "llvm/Transforms/Scalar/GVN.h"
91+
#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
9092
#include "llvm/Transforms/Scalar/JumpThreading.h"
9193
#include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
9294
#include "llvm/Transforms/Utils.h"
@@ -897,6 +899,15 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
897899
MPM.addPass(SYCLPropagateAspectsUsagePass());
898900
});
899901

902+
// Add the InferAddressSpaces pass for all the SPIR[V] targets
903+
if (TargetTriple.isSPIR() || TargetTriple.isSPIRV()) {
904+
PB.registerOptimizerLastEPCallback(
905+
[](ModulePassManager &MPM, OptimizationLevel Level) {
906+
MPM.addPass(createModuleToFunctionPassAdaptor(
907+
InferAddressSpacesPass(clang::targets::SPIR_GENERIC_AS)));
908+
});
909+
}
910+
900911
bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
901912
bool IsLTO = CodeGenOpts.PrepareForLTO;
902913

@@ -999,7 +1010,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
9991010
// -fsycl-instrument-device-code option was passed. This option can be used
10001011
// only with spir triple.
10011012
if (LangOpts.SYCLIsDevice && CodeGenOpts.SPIRITTAnnotations) {
1002-
assert(llvm::Triple(TheModule->getTargetTriple()).isSPIR() &&
1013+
assert(TargetTriple.isSPIR() &&
10031014
"ITT annotations can only be added to a module with spir target");
10041015
MPM.addPass(SPIRITTAnnotationsPass());
10051016
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -O1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64 -emit-llvm %s -o - | FileCheck %s
2+
3+
// Test that address spaces are deduced correctly by compiler optimizations.
4+
5+
#include "sycl.hpp"
6+
7+
using namespace sycl;
8+
9+
void foo(const float *usm_in, float* usm_out) {
10+
queue Q;
11+
Q.submit([&](handler &cgh) {
12+
cgh.single_task<class test>([=](){
13+
*usm_out = *usm_in;
14+
});
15+
});
16+
}
17+
18+
// No addrspacecast before loading and storing values
19+
// CHECK-NOT: addrspacecast
20+
// CHECK: %0 = load float, ptr addrspace(1)
21+
// CHECK: store float %0, ptr addrspace(1)

0 commit comments

Comments
 (0)