File: Utils.h

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (104 lines) | stat: -rw-r--r-- 2,880 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*========================== begin_copyright_notice ============================

Copyright (C) 2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#pragma once
#include "common/LLVMWarningsPush.hpp"
#include <llvm/IR/Module.h>
#include <llvm/Support/KnownBits.h>
#include <llvm/ADT/Optional.h>
#include "common/LLVMWarningsPop.hpp"
#include "GenISAIntrinsics/GenIntrinsicInst.h"
#include "GenISAIntrinsics/GenIntrinsics.h"
#include "Compiler/CodeGenPublic.h"
#include "Interval.h"

using namespace llvm;
using namespace Intervals;

namespace IGC {

class UnifiedBits
{
public:
    UnifiedBits(unsigned NumBits);
    // Merge new value into the what we already know about the value.
    UnifiedBits& operator+=(llvm::Value* V);
    llvm::Optional<bool> operator[](unsigned BitPosition) const;
    const llvm::Optional<llvm::APInt> getConstant() const;
private:
    llvm::KnownBits KB;
    bool Unset = true;
};

template <typename Fn>
void visitGenIntrinsic(llvm::Module& M, llvm::GenISAIntrinsic::ID ID, Fn Visit)
{
    using namespace llvm;

    for (auto& F : M)
    {
        if (!F.isIntrinsic() || !GenISAIntrinsic::isIntrinsic(&F))
            continue;

        if (GenISAIntrinsic::getIntrinsicID(&F) == ID)
        {
            for (auto* U : F.users())
            {
                IGC_ASSERT_MESSAGE(isa<GenIntrinsicInst>(U), "not a call?");
                if (auto* GII = dyn_cast<GenIntrinsicInst>(U))
                    Visit(GII);
            }
        }
    }
}

UnifiedBits examineRayFlags(const RayDispatchShaderContext& Ctx);

struct PayloadUse
{
    PayloadUse(Instruction* I, const DataLayout& DL, uint64_t Offset) : I(I)
    {
        Type* Ty = nullptr;
        if (auto* LI = dyn_cast<LoadInst>(I))
            Ty = LI->getType();
        else if (auto* SI = dyn_cast<StoreInst>(I))
            Ty = SI->getValueOperand()->getType();

        IGC_ASSERT_MESSAGE(Ty, "unhandled inst!");

        uint64_t Size = DL.getTypeAllocSize(Ty);
        MemInterval = { Offset, Offset + Size - 1 };
    }

    Instruction* I = nullptr;
    Interval MemInterval;
};

// Walks all the uses of the payload pointer and will return true if we know
// how to handle them. `Uses` will be populated with the loads and stores
// along with their region of memory they access as an offset from the base
// of the payload pointer.
// instTypeMask: 1: Load; 2: Store; 3: Load&Store
enum PL_Inst_Type : uint8_t
{
    Invalid = 0,
    Load = 1,
    Store = 2
};

bool collectAnalyzablePayloadUses(
    Value* I,
    const DataLayout& DL,
    SmallVector<PayloadUse, 4>& Uses,
    uint64_t Offset,
    uint32_t instTypeMask = (PL_Inst_Type::Load|PL_Inst_Type::Store));

uint64_t gcd(uint64_t Dividend, uint64_t Divisor);
unsigned gcd(unsigned Dividend, unsigned Divisor);

} // namespace IGC