Skip to content

Commit

Permalink
[InferAddressSpaces] Add InferAddressSpaces pass to pipeline for SPIR (
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
bader authored Nov 21, 2022
1 parent cd832bf commit a3ae0dd
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
19 changes: 19 additions & 0 deletions clang/include/clang/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===---- SPIR.h - Declare SPIR and SPIR-V target interfaces ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

namespace clang {
namespace targets {

// Used by both the SPIR and SPIR-V targets. Code of the generic address space
// for the target
constexpr unsigned SPIR_GENERIC_AS = 4u;

} // namespace targets
} // namespace clang
13 changes: 12 additions & 1 deletion clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Targets/SPIR.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearchOptions.h"
Expand Down Expand Up @@ -87,6 +88,7 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/EarlyCSE.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
#include "llvm/Transforms/Scalar/JumpThreading.h"
#include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
#include "llvm/Transforms/Utils.h"
Expand Down Expand Up @@ -897,6 +899,15 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
MPM.addPass(SYCLPropagateAspectsUsagePass());
});

// Add the InferAddressSpaces pass for all the SPIR[V] targets
if (TargetTriple.isSPIR() || TargetTriple.isSPIRV()) {
PB.registerOptimizerLastEPCallback(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(createModuleToFunctionPassAdaptor(
InferAddressSpacesPass(clang::targets::SPIR_GENERIC_AS)));
});
}

bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
bool IsLTO = CodeGenOpts.PrepareForLTO;

Expand Down Expand Up @@ -999,7 +1010,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// -fsycl-instrument-device-code option was passed. This option can be used
// only with spir triple.
if (LangOpts.SYCLIsDevice && CodeGenOpts.SPIRITTAnnotations) {
assert(llvm::Triple(TheModule->getTargetTriple()).isSPIR() &&
assert(TargetTriple.isSPIR() &&
"ITT annotations can only be added to a module with spir target");
MPM.addPass(SPIRITTAnnotationsPass());
}
Expand Down
21 changes: 21 additions & 0 deletions clang/test/CodeGenSYCL/infer-address-spaces.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %clang_cc1 -O1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64 -emit-llvm %s -o - | FileCheck %s

// Test that address spaces are deduced correctly by compiler optimizations.

#include "sycl.hpp"

using namespace sycl;

void foo(const float *usm_in, float* usm_out) {
queue Q;
Q.submit([&](handler &cgh) {
cgh.single_task<class test>([=](){
*usm_out = *usm_in;
});
});
}

// No addrspacecast before loading and storing values
// CHECK-NOT: addrspacecast
// CHECK: %0 = load float, ptr addrspace(1)
// CHECK: store float %0, ptr addrspace(1)

0 comments on commit a3ae0dd

Please sign in to comment.