File: RangeDumper.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (96 lines) | stat: -rw-r--r-- 2,791 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
//===--- RangeDumper.swift - Dumps escape information ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SIL

let rangeDumper = FunctionPass(name: "dump-ranges") {
  (function: Function, context: FunctionPassContext) in

  var begin: Instruction?
  var ends = Stack<Instruction>(context)
  defer { ends.deinitialize() }
  var interiors = Stack<Instruction>(context)
  defer { interiors.deinitialize() }
  var ins = Stack<Instruction>(context)
  defer { ins.deinitialize() }
  var outs = Stack<Instruction>(context)
  defer { outs.deinitialize() }

  for inst in function.instructions {
    if let sli = inst as? StringLiteralInst {
      switch sli.value {
        case "begin":
          assert(begin == nil, "more than one begin instruction")
          begin = sli
        case "end":
          ends.append(sli)
        case "interior":
          interiors.append(sli)
        case "inside":
          ins.append(sli)
        case "outside":
          outs.append(sli)
        default:
          break
      }
    }
  }
  
  guard let begin = begin else { return }
  
  var instRange = InstructionRange(begin: begin, context)
  defer { instRange.deinitialize() }

  instRange.insert(contentsOf: ends)
  instRange.insert(contentsOf: interiors)

  print("Instruction range in \(function.name):")
  print(instRange)
  print("Block range in \(function.name):")
  print(instRange.blockRange)
  print("End function \(function.name)\n")

  verify(instRange.blockRange, context)
  
  for i in ins {
    assert(instRange.contains(i))
    assert(instRange.inclusiveRangeContains(i))
  }
  for e in ends {
    assert(!instRange.contains(e))
    assert(instRange.inclusiveRangeContains(e))
  }
  for o in outs {
    assert(!instRange.contains(o))
    assert(!instRange.inclusiveRangeContains(o))
  }
}

private func verify(_ blockRange: BasicBlockRange, _ context: FunctionPassContext) {
  var inRange = BasicBlockSet(context)
  defer { inRange.deinitialize() }
  for b in blockRange.range {
    inRange.insert(b)
  }

  var inInclusiveRange = BasicBlockSet(context)
  defer { inInclusiveRange.deinitialize() }
  for b in blockRange.inclusiveRange {
    inInclusiveRange.insert(b)
  }

  for b in blockRange.begin.parentFunction.blocks {
    assert(blockRange.contains(b) == inRange.contains(b))
    assert(blockRange.inclusiveRangeContains(b) == inInclusiveRange.contains(b))
  }
}