1 //===--------------- IRNormalizer.cpp - IR Normalizer ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the IRNormalizer class which aims to transform LLVM
10 /// Modules into a normal form by reordering and renaming instructions while
11 /// preserving the same semantics. The normalizer makes it easier to spot
12 /// semantic differences while diffing two modules which have undergone
13 /// different passes.
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #include "llvm/Transforms/Utils/IRNormalizer.h"
18 #include "llvm/ADT/SetVector.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/IR/BasicBlock.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/IRBuilder.h"
25 #include "llvm/IR/InstIterator.h"
26 #include "llvm/Pass.h"
27 #include <stack>
28
29 #define DEBUG_TYPE "normalize"
30
31 using namespace llvm;
32
33 namespace {
34 /// IRNormalizer aims to transform LLVM IR into normal form.
35 class IRNormalizer {
36 public:
37 bool runOnFunction(Function &F);
38
IRNormalizer(IRNormalizerOptions Options)39 IRNormalizer(IRNormalizerOptions Options) : Options(Options) {}
40
41 private:
42 const IRNormalizerOptions Options;
43
44 // Random constant for hashing, so the state isn't zero.
45 const uint64_t MagicHashConstant = 0x6acaa36bef8325c5ULL;
46 DenseSet<const Instruction *> NamedInstructions;
47
48 SmallVector<Instruction *, 16> Outputs;
49
50 /// \name Naming.
51 /// @{
52 void nameFunctionArguments(Function &F) const;
53 void nameBasicBlocks(Function &F) const;
54 void nameInstruction(Instruction *I);
55 void nameAsInitialInstruction(Instruction *I) const;
56 void nameAsRegularInstruction(Instruction *I);
57 void foldInstructionName(Instruction *I) const;
58 /// @}
59
60 /// \name Reordering.
61 /// @{
62 void reorderInstructions(Function &F) const;
63 void reorderDefinition(Instruction *Definition,
64 std::stack<Instruction *> &TopologicalSort,
65 SmallPtrSet<const Instruction *, 32> &Visited) const;
66 void reorderInstructionOperandsByNames(Instruction *I) const;
67 void reorderPHIIncomingValues(PHINode *Phi) const;
68 /// @}
69
70 /// \name Utility methods.
71 /// @{
72 template <typename T>
73 void sortCommutativeOperands(Instruction *I, T &Operands) const;
74 SmallVector<Instruction *, 16> collectOutputInstructions(Function &F) const;
75 bool isOutput(const Instruction *I) const;
76 bool isInitialInstruction(const Instruction *I) const;
77 bool hasOnlyImmediateOperands(const Instruction *I) const;
78 SetVector<int>
79 getOutputFootprint(Instruction *I,
80 SmallPtrSet<const Instruction *, 32> &Visited) const;
81 /// @}
82 };
83 } // namespace
84
85 /// Entry method to the IRNormalizer.
86 ///
87 /// \param F Function to normalize.
runOnFunction(Function & F)88 bool IRNormalizer::runOnFunction(Function &F) {
89 nameFunctionArguments(F);
90 nameBasicBlocks(F);
91
92 Outputs = collectOutputInstructions(F);
93
94 if (!Options.PreserveOrder)
95 reorderInstructions(F);
96
97 // TODO: Reorder basic blocks via a topological sort.
98
99 for (auto &I : Outputs)
100 nameInstruction(I);
101
102 for (auto &I : instructions(F)) {
103 if (!Options.PreserveOrder) {
104 if (Options.ReorderOperands)
105 reorderInstructionOperandsByNames(&I);
106
107 if (auto *Phi = dyn_cast<PHINode>(&I))
108 reorderPHIIncomingValues(Phi);
109 }
110 foldInstructionName(&I);
111 }
112
113 return true;
114 }
115
116 /// Numbers arguments.
117 ///
118 /// \param F Function whose arguments will be renamed.
nameFunctionArguments(Function & F) const119 void IRNormalizer::nameFunctionArguments(Function &F) const {
120 int ArgumentCounter = 0;
121 for (auto &A : F.args()) {
122 if (Options.RenameAll || A.getName().empty()) {
123 A.setName("a" + Twine(ArgumentCounter));
124 ArgumentCounter += 1;
125 }
126 }
127 }
128
129 /// Names basic blocks using a generated hash for each basic block in
130 /// a function considering the opcode and the order of output instructions.
131 ///
132 /// \param F Function containing basic blocks to rename.
nameBasicBlocks(Function & F) const133 void IRNormalizer::nameBasicBlocks(Function &F) const {
134 for (auto &B : F) {
135 // Initialize to a magic constant, so the state isn't zero.
136 uint64_t Hash = MagicHashConstant;
137
138 // Hash considering output instruction opcodes.
139 for (auto &I : B)
140 if (isOutput(&I))
141 Hash = hashing::detail::hash_16_bytes(Hash, I.getOpcode());
142
143 if (Options.RenameAll || B.getName().empty()) {
144 // Name basic block. Substring hash to make diffs more readable.
145 B.setName("bb" + std::to_string(Hash).substr(0, 5));
146 }
147 }
148 }
149
150 /// Names instructions graphically (recursive) in accordance with the
151 /// def-use tree, starting from the initial instructions (defs), finishing at
152 /// the output (top-most user) instructions (depth-first).
153 ///
154 /// \param I Instruction to be renamed.
nameInstruction(Instruction * I)155 void IRNormalizer::nameInstruction(Instruction *I) {
156 // Ensure instructions are not renamed. This is done
157 // to prevent situation where instructions are used
158 // before their definition (in phi nodes)
159 if (NamedInstructions.contains(I))
160 return;
161 NamedInstructions.insert(I);
162 if (isInitialInstruction(I)) {
163 nameAsInitialInstruction(I);
164 } else {
165 // This must be a regular instruction.
166 nameAsRegularInstruction(I);
167 }
168 }
169
170 template <typename T>
sortCommutativeOperands(Instruction * I,T & Operands) const171 void IRNormalizer::sortCommutativeOperands(Instruction *I, T &Operands) const {
172 if (!(I->isCommutative() && Operands.size() >= 2))
173 return;
174 auto CommutativeEnd = Operands.begin();
175 std::advance(CommutativeEnd, 2);
176 llvm::sort(Operands.begin(), CommutativeEnd);
177 }
178
179 /// Names instruction following the scheme:
180 /// vl00000Callee(Operands)
181 ///
182 /// Where 00000 is a hash calculated considering instruction's opcode and output
183 /// footprint. Callee's name is only included when instruction's type is
184 /// CallInst. In cases where instruction is commutative, operands list is also
185 /// sorted.
186 ///
187 /// Renames instruction only when RenameAll flag is raised or instruction is
188 /// unnamed.
189 ///
190 /// \see getOutputFootprint()
191 /// \param I Instruction to be renamed.
nameAsInitialInstruction(Instruction * I) const192 void IRNormalizer::nameAsInitialInstruction(Instruction *I) const {
193 if (I->getType()->isVoidTy())
194 return;
195 if (!(I->getName().empty() || Options.RenameAll))
196 return;
197 LLVM_DEBUG(dbgs() << "Naming initial instruction: " << *I << "\n");
198
199 // Instruction operands for further sorting.
200 SmallVector<SmallString<64>, 4> Operands;
201
202 // Collect operands.
203 for (auto &Op : I->operands()) {
204 if (!isa<Function>(Op)) {
205 std::string TextRepresentation;
206 raw_string_ostream Stream(TextRepresentation);
207 Op->printAsOperand(Stream, false);
208 Operands.push_back(StringRef(Stream.str()));
209 }
210 }
211
212 sortCommutativeOperands(I, Operands);
213
214 // Initialize to a magic constant, so the state isn't zero.
215 uint64_t Hash = MagicHashConstant;
216
217 // Consider instruction's opcode in the hash.
218 Hash = hashing::detail::hash_16_bytes(Hash, I->getOpcode());
219
220 SmallPtrSet<const Instruction *, 32> Visited;
221 // Get output footprint for I.
222 SetVector<int> OutputFootprint = getOutputFootprint(I, Visited);
223
224 // Consider output footprint in the hash.
225 for (const int &Output : OutputFootprint)
226 Hash = hashing::detail::hash_16_bytes(Hash, Output);
227
228 // Base instruction name.
229 SmallString<256> Name;
230 Name.append("vl" + std::to_string(Hash).substr(0, 5));
231
232 // In case of CallInst, consider callee in the instruction name.
233 if (const auto *CI = dyn_cast<CallInst>(I)) {
234 Function *F = CI->getCalledFunction();
235
236 if (F != nullptr)
237 Name.append(F->getName());
238 }
239
240 Name.append("(");
241 for (size_t i = 0; i < Operands.size(); ++i) {
242 Name.append(Operands[i]);
243
244 if (i < Operands.size() - 1)
245 Name.append(", ");
246 }
247 Name.append(")");
248
249 I->setName(Name);
250 }
251
252 /// Names instruction following the scheme:
253 /// op00000Callee(Operands)
254 ///
255 /// Where 00000 is a hash calculated considering instruction's opcode, its
256 /// operands' opcodes and order. Callee's name is only included when
257 /// instruction's type is CallInst. In cases where instruction is commutative,
258 /// operand list is also sorted.
259 ///
260 /// Names instructions recursively in accordance with the def-use tree,
261 /// starting from the initial instructions (defs), finishing at
262 /// the output (top-most user) instructions (depth-first).
263 ///
264 /// Renames instruction only when RenameAll flag is raised or instruction is
265 /// unnamed.
266 ///
267 /// \see getOutputFootprint()
268 /// \param I Instruction to be renamed.
nameAsRegularInstruction(Instruction * I)269 void IRNormalizer::nameAsRegularInstruction(Instruction *I) {
270 LLVM_DEBUG(dbgs() << "Naming regular instruction: " << *I << "\n");
271
272 // Instruction operands for further sorting.
273 SmallVector<SmallString<128>, 4> Operands;
274
275 // The name of a regular instruction depends
276 // on the names of its operands. Hence, all
277 // operands must be named first in the use-def
278 // walk.
279
280 // Collect operands.
281 for (auto &Op : I->operands()) {
282 if (auto *I = dyn_cast<Instruction>(Op)) {
283 // Walk down the use-def chain.
284 nameInstruction(I);
285 Operands.push_back(I->getName());
286 } else if (!isa<Function>(Op)) {
287 // This must be an immediate value.
288 std::string TextRepresentation;
289 raw_string_ostream Stream(TextRepresentation);
290 Op->printAsOperand(Stream, false);
291 Operands.push_back(StringRef(Stream.str()));
292 }
293 }
294
295 sortCommutativeOperands(I, Operands);
296
297 // Initialize to a magic constant, so the state isn't zero.
298 uint64_t Hash = MagicHashConstant;
299
300 // Consider instruction opcode in the hash.
301 Hash = hashing::detail::hash_16_bytes(Hash, I->getOpcode());
302
303 // Operand opcodes for further sorting (commutative).
304 SmallVector<int, 4> OperandsOpcodes;
305
306 // Collect operand opcodes for hashing.
307 for (auto &Op : I->operands())
308 if (auto *I = dyn_cast<Instruction>(Op))
309 OperandsOpcodes.push_back(I->getOpcode());
310
311 sortCommutativeOperands(I, OperandsOpcodes);
312
313 // Consider operand opcodes in the hash.
314 for (const int Code : OperandsOpcodes)
315 Hash = hashing::detail::hash_16_bytes(Hash, Code);
316
317 // Base instruction name.
318 SmallString<512> Name;
319 Name.append("op" + std::to_string(Hash).substr(0, 5));
320
321 // In case of CallInst, consider callee in the instruction name.
322 if (const auto *CI = dyn_cast<CallInst>(I))
323 if (const Function *F = CI->getCalledFunction())
324 Name.append(F->getName());
325
326 Name.append("(");
327 for (size_t i = 0; i < Operands.size(); ++i) {
328 Name.append(Operands[i]);
329
330 if (i < Operands.size() - 1)
331 Name.append(", ");
332 }
333 Name.append(")");
334
335 if ((I->getName().empty() || Options.RenameAll) && !I->getType()->isVoidTy())
336 I->setName(Name);
337 }
338
339 /// Shortens instruction's name. This method removes called function name from
340 /// the instruction name and substitutes the call chain with a corresponding
341 /// list of operands.
342 ///
343 /// Examples:
344 /// op00000Callee(op00001Callee(...), vl00000Callee(1, 2), ...) ->
345 /// op00000(op00001, vl00000, ...) vl00000Callee(1, 2) -> vl00000(1, 2)
346 ///
347 /// This method omits output instructions and pre-output (instructions directly
348 /// used by an output instruction) instructions (by default). By default it also
349 /// does not affect user named instructions.
350 ///
351 /// \param I Instruction whose name will be folded.
foldInstructionName(Instruction * I) const352 void IRNormalizer::foldInstructionName(Instruction *I) const {
353 // If this flag is raised, fold all regular
354 // instructions (including pre-outputs).
355 if (!Options.FoldPreOutputs) {
356 // Don't fold if one of the users is an output instruction.
357 for (auto *U : I->users())
358 if (auto *IU = dyn_cast<Instruction>(U))
359 if (isOutput(IU))
360 return;
361 }
362
363 // Don't fold if it is an output instruction or has no op prefix.
364 if (isOutput(I) || !I->getName().starts_with("op"))
365 return;
366
367 // Instruction operands.
368 SmallVector<SmallString<64>, 4> Operands;
369
370 for (auto &Op : I->operands()) {
371 if (const auto *I = dyn_cast<Instruction>(Op)) {
372 bool HasNormalName =
373 I->getName().starts_with("op") || I->getName().starts_with("vl");
374
375 Operands.push_back(HasNormalName ? I->getName().substr(0, 7)
376 : I->getName());
377 }
378 }
379
380 sortCommutativeOperands(I, Operands);
381
382 SmallString<256> Name;
383 Name.append(I->getName().substr(0, 7));
384
385 Name.append("(");
386 for (size_t i = 0; i < Operands.size(); ++i) {
387 Name.append(Operands[i]);
388
389 if (i < Operands.size() - 1)
390 Name.append(", ");
391 }
392 Name.append(")");
393
394 I->setName(Name);
395 }
396
397 /// Reorders instructions by walking up the tree from each operand of an output
398 /// instruction and reducing the def-use distance.
399 /// This method assumes that output instructions were collected top-down,
400 /// otherwise the def-use chain may be broken.
401 /// This method is a wrapper for recursive reorderInstruction().
402 ///
403 /// \see reorderInstruction()
reorderInstructions(Function & F) const404 void IRNormalizer::reorderInstructions(Function &F) const {
405 for (auto &BB : F) {
406 LLVM_DEBUG(dbgs() << "Reordering instructions in basic block: "
407 << BB.getName() << "\n");
408 // Find the source nodes of the DAG of instructions in this basic block.
409 // Source nodes are instructions that have side effects, are terminators, or
410 // don't have a parent in the DAG of instructions.
411 //
412 // We must iterate from the first to the last instruction otherwise side
413 // effecting instructions could be reordered.
414
415 std::stack<Instruction *> TopologicalSort;
416 SmallPtrSet<const Instruction *, 32> Visited;
417 for (auto &I : BB) {
418 // First process side effecting and terminating instructions.
419 if (!(isOutput(&I) || I.isTerminator()))
420 continue;
421 LLVM_DEBUG(dbgs() << "\tReordering from source effecting instruction: ";
422 I.dump());
423 reorderDefinition(&I, TopologicalSort, Visited);
424 }
425
426 for (auto &I : BB) {
427 // Process the remaining instructions.
428 //
429 // TODO: Do more a intelligent sorting of these instructions. For example,
430 // seperate between dead instructinos and instructions used in another
431 // block. Use properties of the CFG the order instructions that are used
432 // in another block.
433 if (Visited.contains(&I))
434 continue;
435 LLVM_DEBUG(dbgs() << "\tReordering from source instruction: "; I.dump());
436 reorderDefinition(&I, TopologicalSort, Visited);
437 }
438
439 LLVM_DEBUG(dbgs() << "Inserting instructions into: " << BB.getName()
440 << "\n");
441 // Reorder based on the topological sort.
442 while (!TopologicalSort.empty()) {
443 auto *Instruction = TopologicalSort.top();
444 auto FirstNonPHIOrDbgOrAlloca = BB.getFirstNonPHIOrDbgOrAlloca();
445 if (auto *Call = dyn_cast<CallInst>(&*FirstNonPHIOrDbgOrAlloca)) {
446 if (Call->getIntrinsicID() ==
447 Intrinsic::experimental_convergence_entry ||
448 Call->getIntrinsicID() == Intrinsic::experimental_convergence_loop)
449 FirstNonPHIOrDbgOrAlloca++;
450 }
451 Instruction->moveBefore(FirstNonPHIOrDbgOrAlloca);
452 TopologicalSort.pop();
453 }
454 }
455 }
456
reorderDefinition(Instruction * Definition,std::stack<Instruction * > & TopologicalSort,SmallPtrSet<const Instruction *,32> & Visited) const457 void IRNormalizer::reorderDefinition(
458 Instruction *Definition, std::stack<Instruction *> &TopologicalSort,
459 SmallPtrSet<const Instruction *, 32> &Visited) const {
460 if (Visited.contains(Definition))
461 return;
462 Visited.insert(Definition);
463
464 {
465 const auto *BasicBlock = Definition->getParent();
466 const auto FirstNonPHIOrDbgOrAlloca =
467 BasicBlock->getFirstNonPHIOrDbgOrAlloca();
468 if (FirstNonPHIOrDbgOrAlloca == BasicBlock->end())
469 return; // TODO: Is this necessary?
470 if (Definition->comesBefore(&*FirstNonPHIOrDbgOrAlloca))
471 return; // TODO: Do some kind of ordering for these instructions.
472 }
473
474 for (auto &Operand : Definition->operands()) {
475 if (auto *Op = dyn_cast<Instruction>(Operand)) {
476 if (Op->getParent() != Definition->getParent())
477 continue; // Only reorder instruction within the same basic block
478 reorderDefinition(Op, TopologicalSort, Visited);
479 }
480 }
481
482 LLVM_DEBUG(dbgs() << "\t\tNext in topological sort: "; Definition->dump());
483 if (Definition->isTerminator())
484 return;
485 if (auto *Call = dyn_cast<CallInst>(Definition)) {
486 if (Call->isMustTailCall())
487 return;
488 if (Call->getIntrinsicID() == Intrinsic::experimental_deoptimize)
489 return;
490 if (Call->getIntrinsicID() == Intrinsic::experimental_convergence_entry)
491 return;
492 if (Call->getIntrinsicID() == Intrinsic::experimental_convergence_loop)
493 return;
494 }
495 if (auto *BitCast = dyn_cast<BitCastInst>(Definition)) {
496 if (auto *Call = dyn_cast<CallInst>(BitCast->getOperand(0))) {
497 if (Call->isMustTailCall())
498 return;
499 }
500 }
501
502 TopologicalSort.emplace(Definition);
503 }
504
505 /// Reorders instruction's operands alphabetically. This method assumes
506 /// that passed instruction is commutative. Changing the operand order
507 /// in other instructions may change the semantics.
508 ///
509 /// \param I Instruction whose operands will be reordered.
reorderInstructionOperandsByNames(Instruction * I) const510 void IRNormalizer::reorderInstructionOperandsByNames(Instruction *I) const {
511 // This method assumes that passed I is commutative,
512 // changing the order of operands in other instructions
513 // may change the semantics.
514
515 // Instruction operands for further sorting.
516 SmallVector<std::pair<std::string, Value *>, 4> Operands;
517
518 // Collect operands.
519 for (auto &Op : I->operands()) {
520 if (auto *V = dyn_cast<Value>(Op)) {
521 if (isa<Instruction>(V)) {
522 // This is an an instruction.
523 Operands.push_back(std::pair<std::string, Value *>(V->getName(), V));
524 } else {
525 std::string TextRepresentation;
526 raw_string_ostream Stream(TextRepresentation);
527 Op->printAsOperand(Stream, false);
528 Operands.push_back(std::pair<std::string, Value *>(Stream.str(), V));
529 }
530 }
531 }
532
533 // Sort operands.
534 sortCommutativeOperands(I, Operands);
535
536 // Reorder operands.
537 unsigned Position = 0;
538 for (auto &Op : I->operands()) {
539 Op.set(Operands[Position].second);
540 Position += 1;
541 }
542 }
543
544 /// Reorders PHI node's values according to the names of corresponding basic
545 /// blocks.
546 ///
547 /// \param Phi PHI node to normalize.
reorderPHIIncomingValues(PHINode * Phi) const548 void IRNormalizer::reorderPHIIncomingValues(PHINode *Phi) const {
549 // Values for further sorting.
550 SmallVector<std::pair<Value *, BasicBlock *>, 2> Values;
551
552 // Collect blocks and corresponding values.
553 for (auto &BB : Phi->blocks()) {
554 Value *V = Phi->getIncomingValueForBlock(BB);
555 Values.push_back(std::pair<Value *, BasicBlock *>(V, BB));
556 }
557
558 // Sort values according to the name of a basic block.
559 llvm::sort(Values, [](const std::pair<Value *, BasicBlock *> &LHS,
560 const std::pair<Value *, BasicBlock *> &RHS) {
561 return LHS.second->getName() < RHS.second->getName();
562 });
563
564 // Swap.
565 for (unsigned i = 0; i < Values.size(); ++i) {
566 Phi->setIncomingBlock(i, Values[i].second);
567 Phi->setIncomingValue(i, Values[i].first);
568 }
569 }
570
571 /// Returns a vector of output instructions. An output is an instruction which
572 /// has side-effects or is ReturnInst. Uses isOutput().
573 ///
574 /// \see isOutput()
575 /// \param F Function to collect outputs from.
576 SmallVector<Instruction *, 16>
collectOutputInstructions(Function & F) const577 IRNormalizer::collectOutputInstructions(Function &F) const {
578 // Output instructions are collected top-down in each function,
579 // any change may break the def-use chain in reordering methods.
580 SmallVector<Instruction *, 16> Outputs;
581 for (auto &I : instructions(F))
582 if (isOutput(&I))
583 Outputs.push_back(&I);
584 return Outputs;
585 }
586
587 /// Helper method checking whether the instruction may have side effects or is
588 /// ReturnInst.
589 ///
590 /// \param I Considered instruction.
isOutput(const Instruction * I) const591 bool IRNormalizer::isOutput(const Instruction *I) const {
592 // Outputs are such instructions which may have side effects or is ReturnInst.
593 return I->mayHaveSideEffects() || isa<ReturnInst>(I);
594 }
595
596 /// Helper method checking whether the instruction has users and only
597 /// immediate operands.
598 ///
599 /// \param I Considered instruction.
isInitialInstruction(const Instruction * I) const600 bool IRNormalizer::isInitialInstruction(const Instruction *I) const {
601 // Initial instructions are such instructions whose values are used by
602 // other instructions, yet they only depend on immediate values.
603 return !I->user_empty() && hasOnlyImmediateOperands(I);
604 }
605
606 /// Helper method checking whether the instruction has only immediate operands.
607 ///
608 /// \param I Considered instruction.
hasOnlyImmediateOperands(const Instruction * I) const609 bool IRNormalizer::hasOnlyImmediateOperands(const Instruction *I) const {
610 for (const auto &Op : I->operands())
611 if (isa<Instruction>(Op))
612 return false; // Found non-immediate operand (instruction).
613 return true;
614 }
615
616 /// Helper method returning indices (distance from the beginning of the basic
617 /// block) of outputs using the \p I (eliminates repetitions). Walks down the
618 /// def-use tree recursively.
619 ///
620 /// \param I Considered instruction.
621 /// \param Visited Set of visited instructions.
getOutputFootprint(Instruction * I,SmallPtrSet<const Instruction *,32> & Visited) const622 SetVector<int> IRNormalizer::getOutputFootprint(
623 Instruction *I, SmallPtrSet<const Instruction *, 32> &Visited) const {
624
625 // Vector containing indexes of outputs (no repetitions),
626 // which use I in the order of walking down the def-use tree.
627 SetVector<int> Outputs;
628
629 if (!Visited.count(I)) {
630 Visited.insert(I);
631
632 if (isOutput(I)) {
633 // Gets output instruction's parent function.
634 Function *Func = I->getParent()->getParent();
635
636 // Finds and inserts the index of the output to the vector.
637 unsigned Count = 0;
638 for (const auto &B : *Func) {
639 for (const auto &E : B) {
640 if (&E == I)
641 Outputs.insert(Count);
642 Count += 1;
643 }
644 }
645
646 // Returns to the used instruction.
647 return Outputs;
648 }
649
650 for (auto *U : I->users()) {
651 if (auto *UI = dyn_cast<Instruction>(U)) {
652 // Vector for outputs which use UI.
653 SetVector<int> OutputsUsingUI = getOutputFootprint(UI, Visited);
654 // Insert the indexes of outputs using UI.
655 Outputs.insert_range(OutputsUsingUI);
656 }
657 }
658 }
659
660 // Return to the used instruction.
661 return Outputs;
662 }
663
run(Function & F,FunctionAnalysisManager & AM) const664 PreservedAnalyses IRNormalizerPass::run(Function &F,
665 FunctionAnalysisManager &AM) const {
666 IRNormalizer(Options).runOnFunction(F);
667 PreservedAnalyses PA;
668 PA.preserveSet<CFGAnalyses>();
669 return PA;
670 }
671