summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-legalize-global-values.h
blob: 87b9fccc2f09ad848709ccd0f375a25ad125741e (plain)
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
#pragma once

#include "core/slang-dictionary.h"

namespace Slang
{
struct IRBuilder;
struct IRCloneEnv;
struct IRInst;
struct IRModule;

struct GlobalInstInliningContextGeneric
{
    Dictionary<IRInst*, bool> m_mapGlobalInstToShouldInline;
    bool wrapReferences = true;

    // Target-specific control over how inlining happens
    virtual bool isLegalGlobalInstForTarget(IRInst* inst) = 0;
    virtual bool isInlinableGlobalInstForTarget(IRInst* inst) = 0;
    virtual bool shouldBeInlinedForTarget(IRInst* user) = 0;
    virtual IRInst* getOutsideASM(IRInst* beforeInst) = 0;

    // Inline global values that can't represented by the target to their use sites.
    // If this leaves any global unused, then remove it.
    void inlineGlobalValuesAndRemoveIfUnused(IRModule* module);

    // Opcodes that can exist in global scope, as long as the operands are.
    bool isLegalGlobalInst(IRInst* inst);

    // Opcodes that can be inlined into function bodies.
    bool isInlinableGlobalInst(IRInst* inst);

    bool shouldInlineInstImpl(IRInst* inst);

    bool shouldInlineInst(IRInst* inst);

    IRInst* inlineInst(IRBuilder& builder, IRCloneEnv& cloneEnv, IRInst* inst);

    /// Inline `inst` in the local function body so they can be emitted as a local inst.
    ///
    IRInst* maybeInlineGlobalValue(
        IRBuilder& builder,
        IRInst* user,
        IRInst* inst,
        IRCloneEnv& cloneEnv);
};

// For global constant values that are resource typed or struct containing resource types,
// we need to inline their uses to concrete function bodies so they can be legalized during
// resource legalization.
void inlineGlobalConstantsForLegalization(IRModule* module);


} // namespace Slang