Skip to content

Commit

Permalink
Avoid unecessary looping in GenericAddressDynamicResolution
Browse files Browse the repository at this point in the history
Avoid looping through all instructions on each visit.
  • Loading branch information
stefan-il authored and igcbot committed Feb 4, 2025
1 parent 18183da commit 17cfab3
Showing 1 changed file with 52 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ SPDX-License-Identifier: MIT
#include "Compiler/CISACodeGen/OpenCLKernelCodeGen.hpp"
#include "Compiler/IGCPassSupport.h"
#include "Compiler/MetaDataUtilsWrapper.h"

#include "common/LLVMWarningsPush.hpp"
#include "llvmWrapper/Support/Alignment.h"
#include "llvmWrapper/IR/DerivedTypes.h"
#include <llvm/ADT/SmallVector.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/DataLayout.h>
Expand All @@ -32,34 +34,33 @@ namespace {
class GenericAddressDynamicResolution : public FunctionPass {
public:
static char ID;
Module* m_module = nullptr;
CodeGenContext* m_ctx = nullptr;

GenericAddressDynamicResolution()
: FunctionPass(ID)
{
}
~GenericAddressDynamicResolution() = default;

virtual StringRef getPassName() const override
StringRef getPassName() const override
{
return "GenericAddressDynamicResolution";
}

virtual void getAnalysisUsage(AnalysisUsage& AU) const override
void getAnalysisUsage(AnalysisUsage& AU) const override
{
AU.addRequired<MetaDataUtilsWrapper>();
AU.addRequired<CodeGenContextWrapper>();
AU.addRequired<CastToGASAnalysis>();
}

virtual bool runOnFunction(Function& F) override;

bool runOnFunction(Function& F) override;
private:
bool visitLoadStoreInst(Instruction& I);
bool visitIntrinsicCall(CallInst& I);
Module* getModule() { return m_module; }

private:
Module* m_module = nullptr;
CodeGenContext* m_ctx = nullptr;
llvm::SmallVector<Instruction*, 32> generatedLoadStores;
bool m_needPrivateBranches = false;
bool m_needLocalBranches = false;

Expand Down Expand Up @@ -96,43 +97,37 @@ bool GenericAddressDynamicResolution::runOnFunction(Function& F)
m_needLocalBranches = !GI.isNoLocalToGenericOptionEnabled() && GI.canGenericPointToLocal(F);

bool modified = false;
bool changed = false;

// iterate for all the intrinisics used by to_local, to_global, and to_private
do {
changed = false;

for (inst_iterator i = inst_begin(F); i != inst_end(F); ++i) {
Instruction& instruction = (*i);
llvm::SmallVector<Instruction*, 32> callInstructions;
llvm::SmallVector<Instruction*, 32> loadStoreInstructions;

if (CallInst * intrinsic = dyn_cast<CallInst>(&instruction)) {
changed = visitIntrinsicCall(*intrinsic);
}
for (auto& instruction: llvm::instructions(F)) {

if (changed) {
modified = true;
break;
}
if (isa<CallInst>(&instruction)) {
callInstructions.push_back(&instruction);
}
if (isa<LoadInst, StoreInst>(instruction)) {
loadStoreInstructions.push_back(&instruction);
}
} while (changed);
}
// iterate for all the intrinisics used by to_local, to_global, and to_private
for (auto* callInst : callInstructions) {
modified |= visitIntrinsicCall(cast<CallInst>(*callInst));
}

// iterate over all loads/stores with generic address space pointers
do {
changed = false;

for (inst_iterator i = inst_begin(F); i != inst_end(F); ++i) {
Instruction& instruction = (*i);

if (isa<LoadInst>(instruction) || isa<StoreInst>(instruction)) {
changed = visitLoadStoreInst(instruction);
}
for (auto* loadStoreInst : loadStoreInstructions) {
modified |= visitLoadStoreInst(*loadStoreInst);
}

if (changed) {
modified = true;
break;
}
// iterate over all newly generated load/stores
while (!generatedLoadStores.empty()) {
llvm::SmallVector<Instruction*, 32> newInstructions = generatedLoadStores;
generatedLoadStores.clear();
for (auto* loadStoreInst : newInstructions) {
modified |= visitLoadStoreInst(*loadStoreInst);
}
} while (changed);
}

if (m_numAdditionalControlFlows)
{
Expand All @@ -155,8 +150,7 @@ bool GenericAddressDynamicResolution::runOnFunction(Function& F)

Type* GenericAddressDynamicResolution::getPointerAsIntType(LLVMContext& ctx, const unsigned AS)
{
Module* pModule = getModule();
DataLayout dataLayout = pModule->getDataLayout();
DataLayout dataLayout = m_module->getDataLayout();
unsigned ptrBits(dataLayout.getPointerSizeInBits(AS));
return IntegerType::get(ctx, ptrBits);
}
Expand All @@ -168,11 +162,11 @@ bool GenericAddressDynamicResolution::visitLoadStoreInst(Instruction& I)
Value* pointerOperand = nullptr;
unsigned int pointerAddressSpace = ADDRESS_SPACE_NUM_ADDRESSES;

if (LoadInst * load = dyn_cast<LoadInst>(&I)) {
if (auto* load = dyn_cast<LoadInst>(&I)) {
pointerOperand = load->getPointerOperand();
pointerAddressSpace = load->getPointerAddressSpace();
}
else if (StoreInst * store = dyn_cast<StoreInst>(&I)) {
else if (auto* store = dyn_cast<StoreInst>(&I)) {
pointerOperand = store->getPointerOperand();
pointerAddressSpace = store->getPointerAddressSpace();
}
Expand Down Expand Up @@ -241,7 +235,7 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
// with the corresponding address space.

IGCLLVM::IRBuilder<> builder(&I);
PointerType* pointerType = dyn_cast<PointerType>(pointerOperand->getType());
auto* pointerType = dyn_cast<PointerType>(pointerOperand->getType());
IGC_ASSERT( pointerType != nullptr );
ConstantInt* privateTag = builder.getInt64(1); // tag 001
ConstantInt* localTag = builder.getInt64(2); // tag 010
Expand Down Expand Up @@ -275,15 +269,18 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
builder.SetInsertPoint(BB);
PointerType* ptrType = IGCLLVM::getWithSamePointeeType(pointerType, addressSpace);
Value* ptr = builder.CreateAddrSpaceCast(pointerOperand, ptrType);
Instruction* generatedLoadStore = nullptr;

if (LoadInst* LI = dyn_cast<LoadInst>(&I))
if (auto* LI = dyn_cast<LoadInst>(&I))
{
load = builder.CreateAlignedLoad(LI->getType(), ptr, getAlign(*LI), LI->isVolatile(), LoadName);
generatedLoadStore = cast<Instruction>(load);
}
else if (StoreInst* SI = dyn_cast<StoreInst>(&I))
else if (auto* SI = dyn_cast<StoreInst>(&I))
{
builder.CreateAlignedStore(I.getOperand(0), ptr, getAlign(*SI), SI->isVolatile());
generatedLoadStore = builder.CreateAlignedStore(I.getOperand(0), ptr, getAlign(*SI), SI->isVolatile());
}
generatedLoadStores.push_back(generatedLoadStore);

builder.CreateBr(convergeBlock);
return BB;
Expand Down Expand Up @@ -345,22 +342,25 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
void GenericAddressDynamicResolution::resolveGASWithoutBranches(Instruction& I, Value* pointerOperand)
{
IGCLLVM::IRBuilder<> builder(&I);
PointerType* pointerType = dyn_cast<PointerType>(pointerOperand->getType());
auto* pointerType = dyn_cast<PointerType>(pointerOperand->getType());
IGC_ASSERT( pointerType != nullptr );

Value* nonLocalLoad = nullptr;
Instruction* generatedLoadStore = nullptr;

PointerType* ptrType = IGCLLVM::getWithSamePointeeType(pointerType, ADDRESS_SPACE_GLOBAL);
Value* globalPtr = builder.CreateAddrSpaceCast(pointerOperand, ptrType);

if (LoadInst* LI = dyn_cast<LoadInst>(&I))
if (auto* LI = dyn_cast<LoadInst>(&I))
{
nonLocalLoad = builder.CreateAlignedLoad(LI->getType(), globalPtr, getAlign(*LI), LI->isVolatile(), "globalOrPrivateLoad");
generatedLoadStore = cast<Instruction>(nonLocalLoad);
}
else if (StoreInst* SI = dyn_cast<StoreInst>(&I))
else if (auto* SI = dyn_cast<StoreInst>(&I))
{
builder.CreateAlignedStore(I.getOperand(0), globalPtr, getAlign(*SI), SI->isVolatile());
generatedLoadStore = builder.CreateAlignedStore(I.getOperand(0), globalPtr, getAlign(*SI), SI->isVolatile());
}
generatedLoadStores.push_back(generatedLoadStore);

if (nonLocalLoad != nullptr)
{
Expand All @@ -386,12 +386,12 @@ bool GenericAddressDynamicResolution::visitIntrinsicCall(CallInst& I)
{
IGC_ASSERT(IGCLLVM::getNumArgOperands(&I) == 1);
Value* arg = I.getArgOperand(0);
PointerType* dstType = dyn_cast<PointerType>(I.getType());
auto* dstType = dyn_cast<PointerType>(I.getType());
IGC_ASSERT( dstType != nullptr );
const unsigned targetAS = cast<PointerType>(I.getType())->getAddressSpace();

IGCLLVM::IRBuilder<> builder(&I);
PointerType* pointerType = dyn_cast<PointerType>(arg->getType());
auto* pointerType = dyn_cast<PointerType>(arg->getType());
IGC_ASSERT( pointerType != nullptr );
ConstantInt* globalTag = builder.getInt64(0); // tag 000/111
ConstantInt* privateTag = builder.getInt64(1); // tag 001
Expand All @@ -411,7 +411,7 @@ bool GenericAddressDynamicResolution::visitIntrinsicCall(CallInst& I)
// Force distinguishing private and global pointers if a kernel uses explicit casts.
// For more details please refer to section "Generic Address Space Explicit Casts" in
// documentation directory under igc/generic-pointers/generic-pointers.md
auto ClContext = static_cast<OpenCLProgramContext*>(m_ctx);
auto* ClContext = static_cast<OpenCLProgramContext*>(m_ctx);
ClContext->setDistinguishBetweenPrivateAndGlobalPtr(true);
}

Expand Down

0 comments on commit 17cfab3

Please sign in to comment.