Quick compiler: fix for missing defs

When the verifier replaces a Dex instruction, it may cause us
to lose a definition, making the SSA graph invalid.  This CL
deals with this situation by introducing dummy definitions.

With this CL, run-tests 042 and 075 pass.  The only remaining
run-test failures are related to missing exception edges in the CFG.
The old compiler could infer some of them, while llvm requires all
to be explicit.

Change-Id: I471fa515d8717aa102713a05b0e4115bf656b78e
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 7420bda..1ecf61a 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -420,6 +420,7 @@
       irb(NULL),
       placeholderBB(NULL),
       entryBB(NULL),
+      entryTargetBB(NULL),
       tempName(0),
       requireShadowFrame(false),
       numShadowFrameEntries(0),
@@ -589,6 +590,7 @@
   greenland::IRBuilder* irb;
   llvm::BasicBlock* placeholderBB;
   llvm::BasicBlock* entryBB;
+  llvm::BasicBlock* entryTargetBB;
   std::string bitcode_filename;
   GrowableList llvmValues;
   int32_t tempName;
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index 3eb6a89..83ebf9b 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -53,6 +53,9 @@
   placeholder->replaceAllUsesWith(val);
   val->takeName(placeholder);
   cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
+  llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
+  DCHECK(inst != NULL);
+  inst->eraseFromParent();
 }
 
 llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
@@ -334,7 +337,6 @@
   args.push_back(cUnit->irb->getInt32(info1));
   args.push_back(cUnit->irb->getInt32(info2));
   cUnit->irb->CreateCall(func, args);
-  cUnit->irb->CreateUnreachable();
 }
 
 void emitSuspendCheck(CompilationUnit* cUnit)
@@ -1755,7 +1757,9 @@
     }
   }
 
-  if ((bb->fallThrough != NULL) && !bb->hasReturn) {
+  if (bb->blockType == kEntryBlock) {
+    cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
+  } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
     cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
   }
 
@@ -1891,16 +1895,13 @@
   arg_iter++;  /* Skip path method */
   for (int i = 0; i < cUnit->numSSARegs; i++) {
     llvm::Value* val;
-    llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
-    if (i < cUnit->numRegs) {
-      // Skip non-argument _0 names - should never be a use
-      oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
-    } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
+    if ((i < cUnit->numRegs) || (i >= (cUnit->numRegs + cUnit->numIns))) {
       // Handle SSA defs, skipping Method* and compiler temps
       if (SRegToVReg(cUnit, i) < 0) {
         val = NULL;
       } else {
-        val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
+        llvm::Constant* immValue = cUnit->irb->GetJInt(0);
+        val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
         val->setName(llvmSSAName(cUnit, i));
       }
       oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
@@ -1920,12 +1921,43 @@
       }
     }
   }
-  cUnit->irb->CreateBr(cUnit->placeholderBB);
 
   oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
                                 kPreOrderDFSTraversal, false /* Iterative */);
 
-  cUnit->placeholderBB->eraseFromParent();
+  /*
+   * In a few rare cases of verification failure, the verifier will
+   * replace one or more Dalvik opcodes with the special
+   * throw-verification-failure opcode.  This can leave the SSA graph
+   * in an invalid state, as definitions may be lost, while uses retained.
+   * To work around this problem, we insert placeholder definitions for
+   * all Dalvik SSA regs in the "placeholder" block.  Here, after
+   * bitcode conversion is complete, we examine those placeholder definitions
+   * and delete any with no references (which normally is all of them).
+   *
+   * If any definitions remain, we link the placeholder block into the
+   * CFG.  Otherwise, it is deleted.
+   */
+  for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
+       itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
+    llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
+    DCHECK(inst != NULL);
+    llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
+    DCHECK(val != NULL);
+    if (val->getNumUses() == 0) {
+      inst->eraseFromParent();
+    }
+  }
+  setDexOffset(cUnit, 0);
+  if (cUnit->placeholderBB->empty()) {
+    cUnit->placeholderBB->eraseFromParent();
+  } else {
+    cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
+    cUnit->irb->CreateBr(cUnit->entryTargetBB);
+    cUnit->entryTargetBB = cUnit->placeholderBB;
+  }
+  cUnit->irb->SetInsertPoint(cUnit->entryBB);
+  cUnit->irb->CreateBr(cUnit->entryTargetBB);
 
   llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);