1 //===- NoopInsertion.cpp - Noop Insertion ---------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass adds fine-grained diversity by displacing code using randomly
11 // placed (optionally target supplied) Noop instructions.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/CodeGen/NoopInsertion.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/IR/BasicBlock.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/Support/Allocator.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/RandomNumberGenerator.h"
27 #include "llvm/Target/TargetInstrInfo.h"
30 #define DEBUG_TYPE "noop-insertion"
32 static cl::opt<unsigned> NoopInsertionPercentage(
33 "noop-insertion-percentage",
34 cl::desc("Percentage of instructions that have Noops prepended"),
35 cl::init(25)); // Default is a good balance between entropy and
38 static cl::opt<unsigned> MaxNoopsPerInstruction(
39 "max-noops-per-instruction",
40 llvm::cl::desc("Maximum number of Noops per instruction"),
43 STATISTIC(InsertedNoops,
44 "Total number of noop type instructions inserted for diversity");
46 char NoopInsertion::ID = 0;
47 char &llvm::NoopInsertionID = NoopInsertion::ID;
48 INITIALIZE_PASS(NoopInsertion, "noop-insertion",
49 "Noop Insertion for fine-grained code randomization", false,
52 NoopInsertion::NoopInsertion() : MachineFunctionPass(ID) {
53 initializeNoopInsertionPass(*PassRegistry::getPassRegistry());
55 // clamp percentage to 100
56 if (NoopInsertionPercentage > 100)
57 NoopInsertionPercentage = 100;
60 void NoopInsertion::getAnalysisUsage(AnalysisUsage &AU) const {
62 MachineFunctionPass::getAnalysisUsage(AU);
65 bool NoopInsertion::runOnMachineFunction(MachineFunction &Fn) {
66 // The RNG must be initialized on first use so we have a Module to
69 RNG.reset(Fn.getFunction()->getParent()->createRNG(this));
71 const TargetInstrInfo *TII = Fn.getSubtarget().getInstrInfo();
73 unsigned FnInsertedNoopCount = 0;
76 MachineBasicBlock::iterator FirstTerm = BB.getFirstTerminator();
78 for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E;
83 // Insert random number of Noop-like instructions.
84 for (unsigned i = 0; i < MaxNoopsPerInstruction; i++) {
85 if (Distribution(*RNG) >= NoopInsertionPercentage)
88 TII->insertNoop(BB, I, *RNG);
90 ++FnInsertedNoopCount;
98 InsertedNoops += FnInsertedNoopCount;
100 return FnInsertedNoopCount > 0;