From 3a3888575d1b27389426e058915fd3208d76cb4b Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Wed, 16 Nov 2022 06:03:21 -0800 Subject: [PATCH 1/2] [InferAddressSpaces] Add InferAddressSpaces pass to pipeline for SPIR Clang generates 'addrspacecast' instructions to align address spaces between alloca/global variables/kernel parameters and flat address space references (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. 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. --- clang/include/clang/Basic/Targets/SPIR.h | 19 +++++++++++++++++++ clang/lib/CodeGen/BackendUtil.cpp | 13 ++++++++++++- .../test/CodeGenSYCL/infer-address-spaces.cpp | 19 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 clang/include/clang/Basic/Targets/SPIR.h create mode 100644 clang/test/CodeGenSYCL/infer-address-spaces.cpp diff --git a/clang/include/clang/Basic/Targets/SPIR.h b/clang/include/clang/Basic/Targets/SPIR.h new file mode 100644 index 0000000000000..95ffda3b8f230 --- /dev/null +++ b/clang/include/clang/Basic/Targets/SPIR.h @@ -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 diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 3908831bb2732..77a60c0678f96 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -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" @@ -86,6 +87,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/Scalar/NewGVN.h" @@ -894,6 +896,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; @@ -996,7 +1007,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()); } diff --git a/clang/test/CodeGenSYCL/infer-address-spaces.cpp b/clang/test/CodeGenSYCL/infer-address-spaces.cpp new file mode 100644 index 0000000000000..accf36947df43 --- /dev/null +++ b/clang/test/CodeGenSYCL/infer-address-spaces.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -O1 -fsycl-is-device -internal-isystem %S/Inputs -triple spir64 -emit-llvm %s -o - | FileCheck %s + +#include "sycl.hpp" + +using namespace sycl; + +void foo(const float *usm_in, float* usm_out) { + queue Q; + Q.submit([&](handler &cgh) { + cgh.single_task([=](){ + *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) From 1345fee814364e0f25234c1a3d272e97260dc11a Mon Sep 17 00:00:00 2001 From: Alexey Bader Date: Wed, 16 Nov 2022 07:30:50 -0800 Subject: [PATCH 2/2] Add a comment to the lit test. --- clang/test/CodeGenSYCL/infer-address-spaces.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/CodeGenSYCL/infer-address-spaces.cpp b/clang/test/CodeGenSYCL/infer-address-spaces.cpp index accf36947df43..8828462fc8433 100644 --- a/clang/test/CodeGenSYCL/infer-address-spaces.cpp +++ b/clang/test/CodeGenSYCL/infer-address-spaces.cpp @@ -1,5 +1,7 @@ // 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;