summaryrefslogtreecommitdiffstats
path: root/mlir/lib/IR
Commit message (Collapse)AuthorAgeFilesLines
...
* Make sure that type construction arguments are forwarded.River Riddle2019-03-291-2/+1
| | | | PiperOrigin-RevId: 228910216
* Const fold splat vectors/tensors in standard add, sub, and mul opsLei Zhang2019-03-291-0/+26
| | | | | | | | | | | | | The const folding logic is structurally similar, so use a template to abstract the common part. Moved mul(x, 0) to a legalization pattern to be consistent with mul(x, 1). Also promoted getZeroAttr() to be a method on Builder since it is expected to be frequently used. PiperOrigin-RevId: 228891989
* Provide dialect hooks for defining named aliases for AffineMap/IntegerSet/Type.River Riddle2019-03-291-2/+139
| | | | | | The AsmPrinter will then query registered dialects for aliases of symbols used within the module and use them in place. PiperOrigin-RevId: 228831678
* Uniformize composition of AffineApplyOp by constructionNicolas Vasilache2019-03-291-8/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This CL is the 5th on the path to simplifying AffineMap composition. This removes the distinction between normalized single-result AffineMap and more general composed multi-result map. One nice byproduct of making the implementation driven by single-result is that the multi-result extension is a trivial change: the implementation is still single-result and we just use: ``` unsigned idx = getIndexOf(...); map.getResult(idx); ``` This CL also fixes an AffineNormalizer implementation issue related to symbols. Namely it stops performing substitutions on symbols in AffineNormalizer and instead concatenates them all to be consistent with the call to `AffineMap::compose(AffineMap)`. This latter call to `compose` cannot perform simplifications of symbols coming from different maps based on positions only: i.e. dims are applied and renumbered but symbols must be concatenated. The only way to determine whether symbols from different AffineApply are the same is to look at the concrete values. The canonicalizeMapAndOperands is thus extended with behavior to support replacing operands that appear multiple times. Lastly, this CL demonstrates that the implementation is correct by rewriting ComposeAffineMaps using only `makeComposedAffineApply`. The implementation uses a matcher because AffineApplyOp are introduced as composed operations on the fly instead of iteratively forwardSubstituting. For this purpose, a walker would revisit freshly introduced AffineApplyOp. Regardless, ComposeAffineMaps is scheduled to disappear, this CL replaces the implementation based on iterative `forwardSubstitute` by a composed-by-construction `makeComposedAffineApply`. Remaining calls to `forwardSubstitute` will be removed in the next CL. PiperOrigin-RevId: 228830443
* Add a few utilities for terminator management:River Riddle2019-03-292-4/+31
| | | | | | | | | * Get a specific successor operand. * Iterator support for non successor operands. * Fix bug when removing the last operand from the operand list of an Instruction. * Get the argument number for a BlockArgument. PiperOrigin-RevId: 228660898
* Support verbose parsing and printing of terminator operationsAlex Zinenko2019-03-292-2/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | Originally, terminators were special kinds of operation and could not be extended by dialects. Only builtin terminators were supported and they had custom parsers and printers. Currently, "terminator" is a property of an operation, making it possible for dialects to define custom terminators. However, verbose forms of operation syntax were not designed to support terminators that may have a list of successors (each successor contains a block name and an optional operand list). Calling printDefaultOp on a terminator drops all successor information. Dialects are thus required to provide custom parsers and printers for their terminators. Introduce the syntax for the list of successors in the verbose from of the operation. Add support for printing and parsing verbose operations with successors. Note that this does not yet add support for unregistered terminators since "terminator" is a property stored in AsbtractOperation and therefore is only available for registered operations that have an instance of AbstractOperation. Add tests for verbose parsing. It is currently impossible to test round-trip for verbose terminators because none of the known dialects use verbose syntax for printing terminators by default, however the printer was exercised on the LLVM IR dialect prototype. PiperOrigin-RevId: 228566453
* Extract BuiltinOps::canonicalizeMapAndOperandsNicolas Vasilache2019-03-291-27/+41
| | | | | | | | | This CL is the 4th on the path to simplifying AffineMap composition. This CL extract canonicalizeMapAndOperands so it can be reused by other functions; in particular, this will be used in `makeNormalizedAffineApply`. PiperOrigin-RevId: 228277890
* Introduce AffineMap::compose(AffineMap)Nicolas Vasilache2019-03-291-0/+27
| | | | | | | | | | | This CL is the 2nd on the path to simplifying AffineMap composition. This CL uses the now accepted `AffineExpr::compose(AffineMap)` to implement `AffineMap::compose(AffineMap)`. Implications of keeping the simplification function in Analysis are documented where relevant. PiperOrigin-RevId: 228276646
* Introduce AffineExpr::compose(AffineMap)Nicolas Vasilache2019-03-291-1/+6
| | | | | | | | | | | This CL is the 1st on the path to simplifying AffineMap composition. This CL uses the now accepted AffineExpr.replaceDimsAndSymbols to implement `AffineExpr::compose(AffineMap)`. Arguably, `simplifyAffineExpr` should be part of IR and not Analysis but this CL does not yet pull the trigger on that. PiperOrigin-RevId: 228265845
* Extend loop-fusion's slicing utility + other fixes / updatesUday Bondhugula2019-03-291-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | - refactor toAffineFromEq and the code surrounding it; refactor code into FlatAffineConstraints::getSliceBounds - add FlatAffineConstraints methods to detect identifiers as mod's and div's of other identifiers - add FlatAffineConstraints::getConstantLower/UpperBound - Address b/122118218 (don't assert on invalid fusion depths cmdline flags - instead, don't do anything; change cmdline flags src-loop-depth -> fusion-src-loop-depth - AffineExpr/Map print method update: don't fail on null instances (since we have a wrapper around a pointer, it's avoidable); rationale: dump/print methods should never fail if possible. - Update memref-dataflow-opt to add an optimization to avoid a unnecessary call to IsRangeOneToOne when it's trivially going to be true. - Add additional test cases to exercise the new support - update a few existing test cases since the maps are now generated uniformly with all destination loop operands appearing for the backward slice - Fix projectOut - fix wrong range for getBestElimCandidate. - Fix for getConstantBoundOnDimSize() - didn't show up in any test cases since we didn't have any non-hyperrectangular ones. PiperOrigin-RevId: 228265152
* Convert expr - c * (expr floordiv c) to expr mod c in AffineExprUday Bondhugula2019-03-291-0/+23
| | | | | | | | | | | | | | | | | | | - Detect 'mod' to replace the combination of floordiv, mul, and subtract when possible at construction time; when 'c' is a power of two, this reduces the number of operations; also more compact and readable. Update simplifyAdd for this. On a side note: - with the affine expr flattening we have, a mod expression like d0 mod c would be flattened into d0 - c * q, c * q <= d0 <= c*q + c - 1, with 'q' being added as the local variable (q = d0 floordiv c); as a result, a mod was turned into a floordiv whenever the expression was reconstructed back, i.e., as d0 - c * (d0 floordiv c); as a result of this change, we recover the mod back. - rename SimplifyAffineExpr -> SimplifyAffineStructures (pass had been renamed but the file hadn't been). PiperOrigin-RevId: 228258120
* Add support for types belonging to unknown dialects. This allows for types ↵River Riddle2019-03-295-4/+55
| | | | | | to be round tripped even if the dialect that defines them is not linked in. These types will be represented by a new "UnknownType" that uniques them based upon the dialect namespace and raw string type data. PiperOrigin-RevId: 228184629
* Drop all uses of the ForInst induction variable before deleting ForInstAlex Zinenko2019-03-291-0/+7
| | | | | | | | | | | | | | | | The `for` instruction defines the loop induction variable it uses. In the well-formed IR, the induction variable can only be used by the body of the `for` loop. Existing implementation was explicitly cleaning the body of the for loop to remove all uses of the induction variable before removing its definition. However, in ill-formed IR that may appear in some stages of parsing, there may be (invalid) users of the loop induction variable outside the loop body. In case of unsuccessful parsing, destructor of the ForInst-defined Value would assert because there are remaining though invalid users of this Value. Explicitly drop all uses of the loop induction Value when destroying a ForInst. It is no longer necessary to explicitly clean the body of the loop, destructor of the block will take care of this. PiperOrigin-RevId: 228168880
* Rename getAffineBinaryExpr -> getAffineBinaryOpExpr, getBinaryAffineOpExpr ->Uday Bondhugula2019-03-292-3/+3
| | | | | | | | getAffineBinaryOpExpr for consistency (NFC) - this is consistent with the name of the class and getAffineDimExpr/ConstantExpr, etc. PiperOrigin-RevId: 228164959
* Cleanup spurious DenseMap includeNicolas Vasilache2019-03-291-1/+0
| | | | PiperOrigin-RevId: 228059305
* [MLIR] Introduce normalized single-result unbounded AffineApplyOpNicolas Vasilache2019-03-291-33/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Supervectorization does not plan on handling multi-result AffineMaps and non-canonical chains of > 1 AffineApplyOp. This CL introduces a simpler abstraction and composition of single-result unbounded AffineApplyOp by using the existing unbound AffineMap composition. This CL adds a simple API call and relevant tests: ```c++ OpPointer<AffineApplyOp> makeNormalizedAffineApply( FuncBuilder *b, Location loc, AffineMap map, ArrayRef<Value*> operands); ``` which creates a single-result unbounded AffineApplyOp. The operands of AffineApplyOp are not themselves results of AffineApplyOp by consrtuction. This represent the simplest possible interface to complement the composition of (mathematical) AffineMap, for the cases when we are interested in applying it to Value*. In this CL the composed AffineMap is not compressed (i.e. there exist operands that are not part of the result). A followup commit will compress to normal form. The single-result unbounded AffineApplyOp abstraction will be used in a followup CL to support the MaterializeVectors pass. PiperOrigin-RevId: 227879021
* Introduce CRTP TypeBase class to simplify type construction and validation.River Riddle2019-03-293-227/+172
| | | | | | | | | | | | | This impl class currently provides the following: * auto definition of the 'ImplType = StorageClass' * get/getChecked wrappers around TypeUniquer * 'verifyConstructionInvariants' hook - This hook verifies that the arguments passed into get/getChecked are valid to construct a type instance with. With this, all non-generic type uniquing has been moved out of MLIRContext.cpp PiperOrigin-RevId: 227871108
* Introduce a simple canonicalization of affine_apply that drops unused dims andChris Lattner2019-03-294-9/+181
| | | | | | | | | | | | | | | | | | | symbols. Included with this is some other infra: - Testcases for other canonicalizations that I will implement next. - Some helpers in AffineMap/Expr for doing simple walks without defining whole visitor classes. - A 'replaceDimsAndSymbols' facility that I'll be using to simplify maps and exprs, e.g. to fold one constant into a mapping and to drop/renumber unused dims. - Allow index (and everything else) to work in memref's, as we previously discussed, to make the testcase easier to write. - A "getAffineBinaryExpr" helper to produce a binop when you know the kind as an enum. This line of work will eventually subsume the ComposeAffineApply pass, but it is no where close to that yet :-) PiperOrigin-RevId: 227852951
* Split the standard types from builtin types and move them into separate ↵River Riddle2019-03-298-201/+229
| | | | | | source files(StandardTypes.cpp/h). After this cl only FunctionType and IndexType are builtin types, but IndexType will likely become a standard type when the ml/cfgfunc merger is done. Mechanical NFC. PiperOrigin-RevId: 227750918
* Implement initial support for dialect specific types.River Riddle2019-03-295-55/+48
| | | | | | | | | | | | | | | | | | | | | | | | | Dialect specific types are registered similarly to operations, i.e. registerType<...> within the dialect. Unlike operations, there is no notion of a "verbose" type, that is *all* types must be registered to a dialect. Casting support(isa/dyn_cast/etc.) is implemented by reserving a range of type kinds in the top level Type class as opposed to string comparison like operations. To support derived types a few hooks need to be implemented: In the concrete type class: - static char typeID; * A unique identifier for the type used during registration. In the Dialect: - typeParseHook and typePrintHook must be implemented to provide parser support. The syntax for dialect extended types is as follows: dialect-type: '!' dialect-namespace '<' '"' type-specific-data '"' '>' The 'type-specific-data' is information used to identify different types within the dialect, e.g: - !tf<"variant"> // Tensor Flow Variant Type - !tf<"string"> // Tensor Flow String Type TensorFlow/TensorFlowControl types are now implemented as dialect specific types as a proof of concept. PiperOrigin-RevId: 227580052
* Eliminate extfunc/cfgfunc/mlfunc as a concept, and just use 'func' instead.Chris Lattner2019-03-293-41/+15
| | | | | | | | | | | | | The entire compiler now looks at structural properties of the function (e.g. does it have one block, does it contain an if/for stmt, etc) so the only thing holding up this difference is round tripping through the parser/printer syntax. Removing this shrinks the compile by ~140LOC. This is step 31/n towards merging instructions and statements. The last step is updating the docs, which I will do as a separate patch in order to split it from this mostly mechanical patch. PiperOrigin-RevId: 227540453
* Rename OperationPrefix to Namespace in Dialect. This is important as ↵River Riddle2019-03-294-17/+16
| | | | | | | | | | dialects will soon be able to define more than just operations. Moving forward dialect namespaces cannot contain '.' characters. This cl also standardizes that operation names must begin with the dialect namespace followed by a '.'. PiperOrigin-RevId: 227532193
* Introduce PostDominanceInfo, fix properlyDominates() for InstructionsUday Bondhugula2019-03-291-3/+2
| | | | | | | | | | | | | | | - introduce PostDominanceInfo in the right/complete way and use that for post dominance check in store-load forwarding - replace all uses of Analysis/Utils::dominates/properlyDominates with DominanceInfo::dominates/properlyDominates - drop all redundant copies of dominance methods in Analysis/Utils/ - in pipeline-data-transfer, replace dominates call with a much less expensive check; similarly, substitute dominates() in checkMemRefAccessDependence with a simpler check suitable for that context - fix a bug in properlyDominates - improve doc for 'for' instruction 'body' PiperOrigin-RevId: 227320507
* Greatly simplify the ConvertToCFG pass, converting it from a module pass to aChris Lattner2019-03-292-26/+34
| | | | | | | | | | | | | | function pass, and eliminating the need to copy over code and do interprocedural updates. While here, also improve it to make fewer empty blocks, and rename it to "LowerIfAndFor" since that is what it does. This is a net reduction of ~170 lines of code. As drive-bys, change the splitBlock method to *not* insert an unconditional branch, since that behavior is annoying for all clients. Also improve the AsmPrinter to not crash when a block is referenced that isn't linked into a function. PiperOrigin-RevId: 227308856
* Extend InstVisitor and Walker to handle arbitrary CFG functions, expand theChris Lattner2019-03-292-76/+56
| | | | | | | | | | | Function::walk functionality into f->walkInsts/Ops which allows visiting all instructions, not just ops. Eliminate Function::getBody() and Function::getReturn() helpers which crash in CFG functions, and were only kept around as a bridge. This is step 25/n towards merging instructions and statements. PiperOrigin-RevId: 227243966
* Have the asmprinter take advantage of the new capabilities of the asmparser, byChris Lattner2019-03-291-56/+49
| | | | | | | | | | printing the entry block in a CFG function's argument line. Since I'm touching all of the testcases anyway, change the argument list from printing as "%arg : type" to "%arg: type" which is more consistent with bb arguments. In addition to being more consistent, this is a much nicer look for cfg functions. PiperOrigin-RevId: 227240069
* Introduce ^ as a basic block sigil, eliminating an ambiguity on the MLIRChris Lattner2019-03-291-2/+2
| | | | | | syntax. PiperOrigin-RevId: 227234174
* Merge the verifier logic for all functions into a unified framework, thisChris Lattner2019-03-291-10/+7
| | | | | | | | | | requires enhancing DominanceInfo to handle the structure of an ML function, which is required anyway. Along the way, this also fixes a const correctness problem with Instruction::getBlock(). This is step 24/n towards merging instructions and statements. PiperOrigin-RevId: 227228900
* Tidy up references to "basic blocks" that should refer to blocks now. NFC.Chris Lattner2019-03-293-4/+4
| | | | PiperOrigin-RevId: 227196077
* Standardize naming of statements -> instructions, revisting the code base to beChris Lattner2019-03-298-271/+274
| | | | | | | | | consistent and moving the using declarations over. Hopefully this is the last truly massive patch in this refactoring. This is step 21/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227178245
* Rename BasicBlock and StmtBlock to Block, and make a pass cleaning it up. I ↵Chris Lattner2019-03-297-118/+112
| | | | | | | | | | | did not make an effort to rename all of the 'bb' names in the codebase, since they are still correct and any specific missed once can be fixed up on demand. The last major renaming is Statement -> Instruction, which is why Statement and Stmt still appears in various places. This is step 19/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227163082
* Merge ext/cfg/ml function printing logic in the AsmPrinter (shrinking itChris Lattner2019-03-291-460/+359
| | | | | | | | by about 100 LOC), without changing any existing behavior. This is step 20/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227155000
* Eliminate the using decls for MLFunction and CFGFunction standardizing onChris Lattner2019-03-295-30/+28
| | | | | | | | Function. This is step 18/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227139399
* Rename BBArgument -> BlockArgument, Op::getOperation -> Op::getInst(),Chris Lattner2019-03-295-69/+70
| | | | | | | | StmtResult -> InstResult, StmtOperand -> InstOperand, and remove the old names. This is step 17/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227121537
* Merge Operation into OperationInst and standardize nomenclature aroundChris Lattner2019-03-2910-328/+229
| | | | | | | | OperationInst. This is a big mechanical patch. This is step 16/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227093712
* Rework inherentance hierarchy: Operation now derives from Statement, andChris Lattner2019-03-293-70/+5
| | | | | | | | | | | | | OperationInst derives from it. This allows eliminating some forwarding functions, other complex code handling multiple paths, and the 'isStatement' bit tracked by Operation. This is the last patch I think I can make before the big mechanical change merging Operation into OperationInst, coming next. This is step 15/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227077411
* add a method to get FloatAttr value as doubleFeng Liu2019-03-291-1/+10
| | | | | | | | | | | | | | | | | Sometimes we have to get the raw value of the FloatAttr to invoke APIs from non-MLIR libraries (i.e. in the tpu_ops.inc and convert_tensor.cc files). Using `FloatAttr::getValue().convertToFloat()` and `FloatAttr::getValue().convertToDouble()` is not safe because interally they checke the semantics of the APFloat in the attribute, and the semantics is not always specified (the default value is f64 then convertToFloat will fail) or inferred incorrectly (for example, using 1.0 instead of 1.f for IEEEFloat). Calling these convert methods without knowing the semantics can usually crash the compiler. This new method converts the value of a FloatAttr to double even if it loses precision. Currently this method can be used to read in f32 data from arrays. PiperOrigin-RevId: 227076616
* Delicately re-layer Operation, Statement, and OperationStmt, reworkingChris Lattner2019-03-291-1/+1
| | | | | | | | | | | #includes so Statements.h includes Operation.h but nothing else does. This is in preparation to eliminate the Operation class and the complexity it brings with it. I split this patch off because it is just moving stuff around, the next patch will be more complex. This is step 14/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227071777
* Merge CFGFuncBuilder/MLFuncBuilder/FuncBuilder together into a single newChris Lattner2019-03-293-30/+15
| | | | | | | | FuncBuilder class. Also rename SSAValue.cpp to Value.cpp This is step 12/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227067644
* Merge SSAValue, CFGValue, and MLValue together into a single Value class, whichChris Lattner2019-03-297-135/+103
| | | | | | | | | is the new base of the SSA value hierarchy. This CL also standardizes all the nomenclature and comments to use 'Value' where appropriate. This also eliminates a large number of cast<MLValue>(x)'s, which is very soothing. This is step 11/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227064624
* Eliminate the Instruction, BasicBlock, CFGFunction, MLFunction, and ↵Chris Lattner2019-03-2910-762/+213
| | | | | | | | | | | | ExtFunction classes, using the Statement/StmtBlock hierarchy and Function instead. This *only* changes the internal data structures, it does not affect the user visible syntax or structure of MLIR code. Function gets new "isCFG()" sorts of predicates as a transitional measure. This patch is gross in a number of ways, largely in an effort to reduce the amount of mechanical churn in one go. It introduces a bunch of using decls to keep the old names alive for now, and a bunch of stuff needs to be renamed. This is step 10/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 227044402
* Rename findFunction from the ML side of the house to be named getFunction(),Chris Lattner2019-03-296-13/+13
| | | | | | | | | | | | making it more similar to the CFG side of things. It is true that in a deeply nested case that this is not a guaranteed O(1) time operation, and that 'get' could lead compiler hackers to think this is cheap, but we need to merge these and we can look into solutions for this in the future if it becomes a problem in practice. This is step 9/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 226983931
* Inline Instruction's operands as TrailingObjectsMehdi Amini2019-03-291-20/+35
| | | | | | | | | For performance/memory saving purpose, having the Instruction holding a std::vector for the operands isn't a really good tradeoff. The only reason for this was to support adding/removing easily BasicBlock arguments to Terminator. Since this isn't the most common operation, we instead force a pre-allocated list of operands on Instructions at creation time. PiperOrigin-RevId: 226981227
* Eliminate the MLFuncArgument class representing arguments to MLFunctions: ↵Chris Lattner2019-03-294-40/+20
| | | | | | | | | | | use the BlockArgument arguments of the entry block instead. This makes MLFunctions and CFGFunctions work more similarly. This is step 7/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 226966975
* Introduce a new StmtBlockList type to hold a list of StmtBlocks. Use it inChris Lattner2019-03-293-7/+69
| | | | | | | | | MLFunction, IfStmt, ForStmt even though they currently only contain exactly one block in that list. This is step 6/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 226960278
* Support NameLoc and CallSiteLoc for mlir::LocationFeng Liu2019-03-294-0/+101
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The NameLoc can be used to represent a variable, node or method. The CallSiteLoc has two fields, one represents the concrete location and another one represents the caller's location. Multiple CallSiteLocs can be chained as a call stack. For example, the following call stack ``` AAA at file1:1 at file2:135 at file3:34 ``` can be formed by call0: ``` auto name = NameLoc::get("AAA"); auto file1 = FileLineColLoc::get("file1", 1); auto file2 = FileLineColLoc::get("file2", 135); auto file3 = FileLineColLoc::get("file3", 34); auto call2 = CallSiteLoc::get(file2, file3); auto call1 = CallSiteLoc::get(file1, call2); auto call0 = CallSiteLoc::get(name, call1); ``` PiperOrigin-RevId: 226941797
* Rename convenience methods to make type explicit.Jacques Pienaar2019-03-291-3/+7
| | | | PiperOrigin-RevId: 226939383
* Refactor MLFunction to contain a StmtBlock for its body instead of inheritingChris Lattner2019-03-295-25/+21
| | | | | | | | | | from it. This is necessary progress to squaring away the parent relationship that a StmtBlock has with its enclosing if/for/fn, and makes room for functions to have more than one block in the future. This also removes IfClause and ForStmtBody. This is step 5/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 226936541
* Eliminate the ability to add operands to an instruction, used in a narrow caseChris Lattner2019-03-294-61/+16
| | | | | | | | | | | | | | | for SSA values in terminators, but easily worked around. At the same time, move the StmtOperand list in a OperationStmt to the end of its trailing objects list so we can *reduce* the number of operands, without affecting offsets to the other stuff in the allocation. This is important because we want OperationStmts to be consequtive, including their operands - we don't want to use an std::vector of operands like Instructions have. This is patch 4/n towards merging instructions and statements, NFC. PiperOrigin-RevId: 226865727
* Implement StmtBlocks support for arguments and pred/succ iteration. This isn'tChris Lattner2019-03-294-4/+105
| | | | | | tested yet, but will when stuff starts switching over to it. This is part 3/n of merging CFGFunctions and MLFunctions. PiperOrigin-RevId: 226794787
OpenPOWER on IntegriCloud