Subzero: Randomly insert nops.

Adds command line options -nop-insertion, -nop-insertion-probability=X, and -max-nops-per-instruction=X.

BUG=none
R=jvoung@chromium.org, stichnot@chromium.org

Review URL: https://codereview.chromium.org/463563006
diff --git a/src/IceTargetLowering.cpp b/src/IceTargetLowering.cpp
index 0034de5..057a3ea 100644
--- a/src/IceTargetLowering.cpp
+++ b/src/IceTargetLowering.cpp
@@ -22,8 +22,25 @@
 #include "IceTargetLowering.h"
 #include "IceTargetLoweringX8632.h"
 
+#include "llvm/Support/CommandLine.h"
+
 namespace Ice {
 
+namespace {
+
+namespace cl = llvm::cl;
+cl::opt<bool> DoNopInsertion("nop-insertion", cl::desc("Randomly insert NOPs"),
+                             cl::init(false));
+
+cl::opt<int> MaxNopsPerInstruction(
+    "max-nops-per-instruction",
+    cl::desc("Max number of nops to insert per instruction"), cl::init(1));
+
+cl::opt<int> NopProbabilityAsPercentage(
+    "nop-insertion-percentage",
+    cl::desc("Nop insertion probability as percentage"), cl::init(10));
+} // end of anonymous namespace
+
 void LoweringContext::init(CfgNode *N) {
   Node = N;
   Begin = getNode()->getInsts().begin();
@@ -90,6 +107,20 @@
   Context.advanceNext();
 }
 
+bool TargetLowering::shouldDoNopInsertion() const { return DoNopInsertion; }
+
+void TargetLowering::doNopInsertion() {
+  Inst *I = *Context.getCur();
+  bool ShouldSkip = llvm::isa<InstFakeUse>(I) || llvm::isa<InstFakeDef>(I) ||
+                    llvm::isa<InstFakeKill>(I) || I->isRedundantAssign() ||
+                    I->isDeleted();
+  if (!ShouldSkip) {
+    for (int I = 0; I < MaxNopsPerInstruction; ++I) {
+      randomlyInsertNop(NopProbabilityAsPercentage / 100.0);
+    }
+  }
+}
+
 // Lowers a single instruction according to the information in
 // Context, by checking the Context.Cur instruction kind and calling
 // the appropriate lowering method.  The lowering method should insert