Implement induction variables. Pretty print induction variable operands as %i<ssa value number>. Add support for future pretty printing of ML function arguments as %arg<ssa value number>.

Induction variables are implemented by inheriting ForStmt from MLValue. ForStmt provides APIs that make this design decision invisible to the ForStmt users.

This CL in combination with cl/206253643 resolves  http://b/111769060.

PiperOrigin-RevId: 206655937
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index 654db98..3bcec37 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -2086,10 +2086,8 @@
   if (getToken().isNot(Token::percent_identifier))
     return emitError("expected SSA identifier for the loop variable");
 
-  // TODO: create SSA value definition from name
-  StringRef name = getTokenSpelling().drop_front();
-  (void)name;
-
+  auto loc = getToken().getLoc();
+  StringRef inductionVariableName = getTokenSpelling().drop_front();
   consumeToken(Token::percent_identifier);
 
   if (parseToken(Token::equal, "expected ="))
@@ -2116,14 +2114,20 @@
   }
 
   // Create for statement.
-  ForStmt *stmt = builder.createFor(lowerBound, upperBound, step);
+  ForStmt *forStmt = builder.createFor(lowerBound, upperBound, step);
+
+  // Create SSA value definition for the induction variable.
+  addDefinition({inductionVariableName, 0, loc}, forStmt->getInductionVar());
 
   // If parsing of the for statement body fails,
   // MLIR contains for statement with those nested statements that have been
   // successfully parsed.
-  if (parseStmtBlock(static_cast<StmtBlock *>(stmt)))
+  if (parseStmtBlock(forStmt))
     return ParseFailure;
 
+  // Reset insertion point to the current block.
+  builder.setInsertionPoint(forStmt->getBlock());
+
   return ParseSuccess;
 }
 
@@ -2174,6 +2178,9 @@
       return ParseFailure;
   }
 
+  // Reset insertion point to the current block.
+  builder.setInsertionPoint(ifStmt->getBlock());
+
   return ParseSuccess;
 }