File: TestInstructionIteration.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 (77 lines) | stat: -rw-r--r-- 2,850 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
//===--- TestInstructionIteration.swift -----------------------------------===//
//
// 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

/// Tests instruction iteration while modifying the instruction list.
///
/// This pass iterates over the instruction list of the function's block and performs
/// modifications of the instruction list - mostly deleting instructions.
/// Modifications are triggered by `string_literal` instructions with known "commands".
/// E.g. if a
/// ```
///   %1 = string_literal utf8 "delete_strings"
/// ```
/// is encountered during the iteration, it triggers the deletion of all `string_literal`
/// instructions of the basic block (including the current one).
let testInstructionIteration = FunctionPass(name: "test-instruction-iteration") {
  (function: Function, context: FunctionPassContext) in

  print("Test instruction iteration in \(function.name):")

  let reverse = function.name.string.hasSuffix("backward")

  for block in function.blocks {
    print("\(block.name):")
    let termLoc = block.terminator.location
    if reverse {
      for inst in block.instructions.reversed() {
        handle(instruction: inst, context)
      }
    } else {
      for inst in block.instructions {
        handle(instruction: inst, context)
      }
    }
    if block.instructions.isEmpty || !(block.instructions.reversed().first is TermInst) {
      let builder = Builder(atEndOf: block, location: termLoc, context)
      builder.createUnreachable()
    }
  }
  print("End function \(function.name):")
}

private func handle(instruction: Instruction, _ context: FunctionPassContext) {
  print(instruction)
  if let sl = instruction as? StringLiteralInst {
    switch sl.value {
      case "delete_strings":
        deleteAllInstructions(ofType: StringLiteralInst.self, in: instruction.parentBlock, context)
      case "delete_ints":
        deleteAllInstructions(ofType: IntegerLiteralInst.self, in: instruction.parentBlock, context)
      case "delete_branches":
        deleteAllInstructions(ofType: BranchInst.self, in: instruction.parentBlock, context)
      case "split_block":
        _ = context.splitBlock(before: instruction)
      default:
        break
    }
  }
}

private func deleteAllInstructions<InstType: Instruction>(ofType: InstType.Type, in block: BasicBlock, _ context: FunctionPassContext) {
  for inst in block.instructions {
    if inst is InstType {
      context.erase(instruction: inst)
    }
  }
}