Subzero: Make optimizations more resilient for early Target development.

A good trick for implementing lowering for a new target is, for not-yet-implemented instructions, to insert a FakeUse of each instruction variable followed by a FakeDef of the dest variable.  Otherwise one risks running afoul of liveness analysis integrity checks.

However, if all the high-level instructions in a basic block lack variables (e.g. unconditional branches, or void calls with only constant arguments), the resulting block may be completely empty.  In O2 mode, this triggers a couple of assertions/errors that wouldn't normally occur:

1. CfgNode::contractIfEmpty() finds a block with a single out-edge that does *not* end with an unconditional branch.

2. CfgNode::livenessAddIntervals() tries to add a bogus liveness interval to a variable because the empty block contains no actual instruction numbers to form a valid interval from.

This adds some fixes/workarounds for those problems.

Another workaround for the empty basic block problem may be to just to add a FakeUse of the stack pointer when lowering an unconditional branch, which combined with the trick above, should prevent empty blocks.  However, these fixes seem reasonable apart from that.

BUG= none
R=sehr@chromium.org

Review URL: https://codereview.chromium.org/1590303002 .
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index e89140e..4e50248 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -257,6 +257,14 @@
   NextInstNumber = Inst::NumberInitial;
   for (CfgNode *Node : Nodes)
     Node->renumberInstructions();
+  // Make sure the entry node is the first node and therefore got the lowest
+  // instruction numbers, to facilitate live range computation of function
+  // arguments.  We want to model function arguments as being live on entry to
+  // the function, otherwise an argument whose only use is in the first
+  // instruction will be assigned a trivial live range and the register
+  // allocator will not recognize its live range as overlapping another
+  // variable's live range.
+  assert(Nodes.empty() || (*Nodes.begin() == getEntryNode()));
 }
 
 // placePhiLoads() must be called before placePhiStores().
@@ -839,14 +847,19 @@
       // instruction of the method is "r=arg1+arg2", both args may be assigned
       // the same register. This is accomplished by extending the entry block's
       // instruction range from [2,n) to [1,n) which will transform the
-      // problematic [2,2) live ranges into [1,2).
+      // problematic [2,2) live ranges into [1,2).  This extension works because
+      // the entry node is guaranteed to have the lowest instruction numbers.
       if (Node == getEntryNode()) {
-        // TODO(stichnot): Make it a strict requirement that the entry node
-        // gets the lowest instruction numbers, so that extending the live
-        // range for in-args is guaranteed to work.
         FirstInstNum = Inst::NumberExtended;
+        // Just in case the entry node somehow contains no instructions...
+        if (LastInstNum == Inst::NumberSentinel)
+          LastInstNum = FirstInstNum;
       }
-      Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
+      // If this node somehow contains no instructions, don't bother trying to
+      // add liveness intervals for it, because variables that are live-in and
+      // live-out will have a bogus interval added.
+      if (FirstInstNum != Inst::NumberSentinel)
+        Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
     }
   }
 }
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 9e3f23a..f06e631 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -852,10 +852,16 @@
     else if (!I.isRedundantAssign())
       return;
   }
+  // Make sure there is actually a successor to repoint in-edges to.
+  if (OutEdges.empty())
+    return;
   assert(OutEdges.size() == 1);
   // Don't try to delete a self-loop.
   if (OutEdges[0] == this)
     return;
+  // Make sure the node actually contains (ends with) an unconditional branch.
+  if (Branch == nullptr)
+    return;
 
   Branch->setDeleted();
   CfgNode *Successor = OutEdges.front();