File: GenXDebugLegalization.cpp

package info (click to toggle)
intel-graphics-compiler 1.0.17791.18-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 102,312 kB
  • sloc: cpp: 935,343; lisp: 286,143; ansic: 16,196; python: 3,279; yacc: 2,487; lex: 1,642; pascal: 300; sh: 174; makefile: 27
file content (137 lines) | stat: -rw-r--r-- 4,323 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*========================== begin_copyright_notice ============================

Copyright (C) 2022-2023 Intel Corporation

SPDX-License-Identifier: MIT

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

//
/// GenXDebugLegalization
/// -----------------
///
/// Modifies incoming metadata to generate valid debug info later on.
///
/// Operation of the pass
/// ^^^^^^^^^^^^^^^^^^^^^
///
/// Remove DW_OP_constu 4/DW_OP_swap/DW_OP_xderef constructs. These are
/// generated by the FE compiler to annotate address space, which is not
/// used (directly) by the debugger.
///
//===----------------------------------------------------------------------===//
#include "GenX.h"
#include "GenXUtil.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "GENX_DEBUGLEGALIZATION"

using namespace llvm;
using namespace genx;

namespace {

// GenXDebugLegalization : reduce integer size
class GenXDebugLegalization : public FunctionPass {

public:
  static char ID;
  explicit GenXDebugLegalization() : FunctionPass(ID) { }
  StringRef getPassName() const override { return "GenX debug legalization"; }
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnFunction(Function &F) override;

private:
  bool extractAddressClass(Function &F);
  bool removeDIArgList(Function &F);
};

} // end anonymous namespace

char GenXDebugLegalization::ID = 0;
namespace llvm { void initializeGenXDebugLegalizationPass(PassRegistry &); }
INITIALIZE_PASS_BEGIN(GenXDebugLegalization, "GenXDebugLegalization", "GenXDebugLegalization", false, false)
INITIALIZE_PASS_END(GenXDebugLegalization, "GenXDebugLegalization", "GenXDebugLegalization", false, false)

FunctionPass *llvm::createGenXDebugLegalizationPass() {
  initializeGenXDebugLegalizationPass(*PassRegistry::getPassRegistry());
  return new GenXDebugLegalization;
}

void GenXDebugLegalization::getAnalysisUsage(AnalysisUsage &AU) const
{
  AU.setPreservesCFG();
}

// Detect instructions with an address class pattern. Then remove all opcodes of this pattern from
// this instruction's last operand (metadata of DIExpression).
// Pattern: !DIExpression(DW_OP_constu, 4, DW_OP_swap, DW_OP_xderef)
bool GenXDebugLegalization::extractAddressClass(Function &F) {
  bool Modified = false;
  DIBuilder di(*F.getParent());

  for (auto& bb : F) {
    for (auto& pInst : bb) {
      if (auto* DI = dyn_cast<DbgVariableIntrinsic>(&pInst)) {
        const DIExpression* DIExpr = DI->getExpression();
        llvm::SmallVector<uint64_t, 5> newElements;
        for (auto I = DIExpr->expr_op_begin(), E = DIExpr->expr_op_end(); I != E; ++I) {
          if (I->getOp() == dwarf::DW_OP_constu) {
            auto patternI = I;
            if (++patternI != E && patternI->getOp() == dwarf::DW_OP_swap &&
                ++patternI != E && patternI->getOp() == dwarf::DW_OP_xderef) {
              I = patternI;
              continue;
            }
          }
          I->appendToVector(newElements);
        }

        if (newElements.size() < DIExpr->getNumElements()) {
          DIExpression* newDIExpr = di.createExpression(newElements);
          DI->setExpression(newDIExpr);
          Modified = true;
        }
      }
    }
  }
  return Modified;
}

// LLVM 12+ may generate DIArgList construct which is not (yet) supported.
// In order to prevent crashes, remove such metadata.
bool GenXDebugLegalization::removeDIArgList(Function &F) {
  bool Modified = false;
  for (auto &BB : F) {
    for (auto &I : BB) {
      if (auto *dbgInst = dyn_cast<DbgVariableIntrinsic>(&I)) {
        if (dbgInst->getNumVariableLocationOps() > 1) {
          dbgInst->setUndef();
          Modified = true;
        }
      }
    }
  }
  return Modified;
}

/***********************************************************************
 * GenXDebugLegalization::runOnFunction : process one function to
 *    reduce integer size where possible
 */
bool GenXDebugLegalization::runOnFunction(Function &F)
{
  bool Modified = false;
  Modified |= extractAddressClass(F);
  Modified |= removeDIArgList(F);
  return Modified;
}