Commit Graph

1090 Commits

Author SHA1 Message Date
MLIR Team fe490043b0 Affine map composition.
*) Implements AffineValueMap forward substitution for AffineApplyOps.
*) Adds ComposeAffineMaps transformation pass, which composes affine maps for all loads/stores in an MLFunction.
*) Adds multiple affine map composition tests.

PiperOrigin-RevId: 216216446
2019-03-29 13:24:59 -07:00
Uday Bondhugula 041817a45e Introduce loop body skewing / loop pipelining / loop shifting utility.
- loopBodySkew shifts statements of a loop body by stmt-wise delays, and is
  typically meant to be used to:
  - allow overlap of non-blocking start/wait until completion operations with
    other computation
  - allow shifting of statements (for better register
    reuse/locality/parallelism)
  - software pipelining (when applied to the innermost loop)
- an additional argument specifies whether to unroll the prologue and epilogue.
- add method to check SSA dominance preservation.
- add a fake loop pipeline pass to test this utility.

Sample input/output are below. While on this, fix/add following:

- fix minor bug in getAddMulPureAffineExpr
- add additional builder methods for common affine map cases
- fix const_operand_iterator's for ForStmt, etc. When there is no such thing
  as 'const MLValue', the iterator shouldn't be returning const MLValue's.
  Returning MLValue is const correct.

Sample input/output examples:

1) Simplest case: shift second statement by one.

Input:

for %i = 0 to 7 {
  %y = "foo"(%i) : (affineint) -> affineint
  %x = "bar"(%i) : (affineint) -> affineint
}

Output:

#map0 = (d0) -> (d0 - 1)
mlfunc @loop_nest_simple1() {
  %c8 = constant 8 : affineint
  %c0 = constant 0 : affineint
  %0 = "foo"(%c0) : (affineint) -> affineint
  for %i0 = 1 to 7 {
    %1 = "foo"(%i0) : (affineint) -> affineint
    %2 = affine_apply #map0(%i0)
    %3 = "bar"(%2) : (affineint) -> affineint
  }
  %4 = affine_apply #map0(%c8)
  %5 = "bar"(%4) : (affineint) -> affineint
  return
}

2) DMA overlap: shift dma.wait and compute by one.

Input
  for %i = 0 to 7 {
    %pingpong = affine_apply (d0) -> (d0 mod 2) (%i)
    "dma.enqueue"(%pingpong) : (affineint) -> affineint
    %pongping = affine_apply (d0) -> (d0 mod 2) (%i)
    "dma.wait"(%pongping) : (affineint) -> affineint
    "compute1"(%pongping) : (affineint) -> affineint
  }

Output

#map0 = (d0) -> (d0 mod 2)
#map1 = (d0) -> (d0 - 1)
#map2 = ()[s0] -> (s0 + 7)
mlfunc @loop_nest_dma() {
  %c8 = constant 8 : affineint
  %c0 = constant 0 : affineint
  %0 = affine_apply #map0(%c0)
  %1 = "dma.enqueue"(%0) : (affineint) -> affineint
  for %i0 = 1 to 7 {
    %2 = affine_apply #map0(%i0)
    %3 = "dma.enqueue"(%2) : (affineint) -> affineint
    %4 = affine_apply #map1(%i0)
    %5 = affine_apply #map0(%4)
    %6 = "dma.wait"(%5) : (affineint) -> affineint
    %7 = "compute1"(%5) : (affineint) -> affineint
  }
  %8 = affine_apply #map1(%c8)
  %9 = affine_apply #map0(%8)
  %10 = "dma.wait"(%9) : (affineint) -> affineint
  %11 = "compute1"(%9) : (affineint) -> affineint
  return
}

3) With arbitrary affine bound maps:

Shift last two statements by two.

Input:

  for %i = %N to ()[s0] -> (s0 + 7)()[%N] {
    %y = "foo"(%i) : (affineint) -> affineint
    %x = "bar"(%i) : (affineint) -> affineint
    %z = "foo_bar"(%i) : (affineint) -> (affineint)
    "bar_foo"(%i) : (affineint) -> (affineint)
  }

Output

#map0 = ()[s0] -> (s0 + 1)
#map1 = ()[s0] -> (s0 + 2)
#map2 = ()[s0] -> (s0 + 7)
#map3 = (d0) -> (d0 - 2)
#map4 = ()[s0] -> (s0 + 8)
#map5 = ()[s0] -> (s0 + 9)

  for %i0 = %arg0 to #map0()[%arg0] {
    %0 = "foo"(%i0) : (affineint) -> affineint
    %1 = "bar"(%i0) : (affineint) -> affineint
  }
  for %i1 = #map1()[%arg0] to #map2()[%arg0] {
    %2 = "foo"(%i1) : (affineint) -> affineint
    %3 = "bar"(%i1) : (affineint) -> affineint
    %4 = affine_apply #map3(%i1)
    %5 = "foo_bar"(%4) : (affineint) -> affineint
    %6 = "bar_foo"(%4) : (affineint) -> affineint
  }
  for %i2 = #map4()[%arg0] to #map5()[%arg0] {
    %7 = affine_apply #map3(%i2)
    %8 = "foo_bar"(%7) : (affineint) -> affineint
    %9 = "bar_foo"(%7) : (affineint) -> affineint
  }

4) Shift one by zero, second by one, third by two

  for %i = 0 to 7 {
    %y = "foo"(%i) : (affineint) -> affineint
    %x = "bar"(%i) : (affineint) -> affineint
    %z = "foobar"(%i) : (affineint) -> affineint
  }

#map0 = (d0) -> (d0 - 1)
#map1 = (d0) -> (d0 - 2)
#map2 = ()[s0] -> (s0 + 7)

  %c9 = constant 9 : affineint
  %c8 = constant 8 : affineint
  %c1 = constant 1 : affineint
  %c0 = constant 0 : affineint
  %0 = "foo"(%c0) : (affineint) -> affineint
  %1 = "foo"(%c1) : (affineint) -> affineint
  %2 = affine_apply #map0(%c1)
  %3 = "bar"(%2) : (affineint) -> affineint
  for %i0 = 2 to 7 {
    %4 = "foo"(%i0) : (affineint) -> affineint
    %5 = affine_apply #map0(%i0)
    %6 = "bar"(%5) : (affineint) -> affineint
    %7 = affine_apply #map1(%i0)
    %8 = "foobar"(%7) : (affineint) -> affineint
  }
  %9 = affine_apply #map0(%c8)
  %10 = "bar"(%9) : (affineint) -> affineint
  %11 = affine_apply #map1(%c8)
  %12 = "foobar"(%11) : (affineint) -> affineint
  %13 = affine_apply #map1(%c9)
  %14 = "foobar"(%13) : (affineint) -> affineint

5) SSA dominance violated; no shifting if a shift is specified for the second
statement.

  for %i = 0 to 7 {
    %x = "foo"(%i) : (affineint) -> affineint
    "bar"(%x) : (affineint) -> affineint
  }

PiperOrigin-RevId: 214975731
2019-03-29 13:21:26 -07:00
Chris Lattner c706e0b1b5 Add support for expected-warning and expected-note markers in mlir-opt -verify
mode.  We even diagnose mistakes nicely (aside from the a/an vowel confusion
which isn't worth worrying about):

test/IR/invalid.mlir split at line tensorflow/mlir#399:8:34: error: 'note' diagnostic emitted when expecting a 'error'
  %x = "bar"() : () -> i32    // expected-error {{operand defined here}}
                                 ^

PiperOrigin-RevId: 214773208
2019-03-29 13:20:46 -07:00
Jacques Pienaar f54861fc4a Add MLIR (addf) -> MLIR HLO thin slice.
Super thin slice that can convert a MLIR program (with addfs) to MLIR HLO dialect. Add this as translations to mlir-translate. Also add hlo::AddOp op and HLO op registration.

PiperOrigin-RevId: 214480409
2019-03-29 13:18:34 -07:00
Jacques Pienaar e5354c2404 Add op registry for registering MLIR ops.
Instead of linking in different initializeMLIRContext functions, add a registry mechanism and function to initialize all registered ops in a given MLIRContext. Initialize all registered ops along with the StandardOps when constructing a MLIRContext.

PiperOrigin-RevId: 214073842
2019-03-29 13:17:49 -07:00
Chris Lattner 82eb284a53 Implement support for constant folding operations and a simple constant folding
optimization pass:

 - Give the ability for operations to implement a constantFold hook (a simple
   one for single-result ops as well as general support for multi-result ops).
 - Implement folding support for constant and addf.
 - Implement support in AbstractOperation and Operation to make this usable by
   clients.
 - Implement a very simple constant folding pass that does top down folding on
   CFG and ML functions, with a testcase that exercises all the above stuff.

Random cleanups:
 - Improve the build APIs for ConstantOp.
 - Stop passing "-o -" to mlir-opt in the testsuite, since that is the default.

PiperOrigin-RevId: 213749809
2019-03-29 13:16:33 -07:00
Jacques Pienaar 81a066e6e7 Switch from positional argument to explicit flags for mlir-translate
This results in uniform behavior with mlir-opt. Exactly one transformation is allowed.

PiperOrigin-RevId: 213493415
2019-03-29 13:15:22 -07:00
Jacques Pienaar 47c7df0ed9 Tool for translating from/to MLIR.
mlir-translate is a tool to translate from/to MLIR. The translations are registered at link time and intended for use in tests. An identity transformation (mlir-to-mlir) is registered by default as example and used in the parser test where simply parsing & printing required.

The TranslateFunctions take filenames (instead of MemoryBuffer) to allow translations special write behavior (e.g., writing to uncommon filesystems).

PiperOrigin-RevId: 213370448
2019-03-29 13:14:37 -07:00
Jacques Pienaar fb3116f59e Add PassResult and have passes return PassResult to indicate failure/success.
For FunctionPass's for passes that want to stop upon error encountered.

PiperOrigin-RevId: 213058651
2019-03-29 13:13:55 -07:00
Chris Lattner 348f31a4fa Add location specifier to MLIR Functions, and:
- Compress the identifier/kind of a Function into a single word.
 - Eliminate otherFailure from verifier now that we always have a location
 - Eliminate the error string from the verifier now that we always have
   locations.
 - Simplify the parser's handling of fn forward references, using the location
   tracked by the function.

PiperOrigin-RevId: 211985101
2019-03-29 13:10:55 -07:00
Chris Lattner 6337af082b Improve location reporting in the verifier for return instructions and other
terminators.  Improve mlir-opt to print better location info in the split-files
case.

Before:

error: unexpected error: branch has 2 operands, but target block has 1
  br bb1(%0tensorflow/mlir#1, %0tensorflow/mlir#0 : i17, i1)
  ^

after:

invalid.mlir split at line tensorflow/mlir#305:6:3: error: unexpected error: branch has 2 operands, but target block has 1
  br bb1(%0tensorflow/mlir#1, %0tensorflow/mlir#0 : i17, i1)
  ^

It still isn't optimal (it would be better to have just the original file and
line number but is a step forward, and doing the optimal thing would be a lot
more complicated.

PiperOrigin-RevId: 211917067
2019-03-29 13:10:38 -07:00
Chris Lattner b18c770d90 Teach RaiseControlFlow to handle IfOp's with partially infered shapes,
inserting shape_casts as necessary.

Along the way:
 - Add some missing accessors to the AtLeastNOperands trait.
 - Implement shape_cast / ShapeCastOp standard op.
 - Improve handling of errors in mlir-opt, making it easier to understand
   errors when invalid IR is rejected by the verifier.

PiperOrigin-RevId: 211897877
2019-03-29 13:10:24 -07:00
Chris Lattner 5f11f68405 Several minor infra improvements:
- Make the tf-lower-control flow handle error cases better.  Add a testcase
   that (currently) fails due to type mismatches.
 - Factor more code in the verifier for basic block argument checking, and
   check more invariants.
 - Fix a crasher in the asmprinter on null instructions (which only occurs on
   invalid code).
 - Fix a bug handling conditional branches with no block operands, it would
   access &operands[0] instead of using operands.data().
 - Enhance the mlir-opt driver to use the verifier() in a non-crashing mode,
   allowing issues to be reported as diagnostics.

PiperOrigin-RevId: 211818291
2019-03-29 13:10:11 -07:00
Jacques Pienaar 95f31d53d5 Add GraphTraits and DOTGraphTraits for CFGFunction in debug builds.
Enable using GraphWriter to dump graphviz in debug mode (kept to debug builds completely as this is only for debugging). Add option to mlir-opt to print CFGFunction after every transform in debug mode.

PiperOrigin-RevId: 211578699
2019-03-29 13:09:31 -07:00
Chris Lattner 6dc2a34dcf Continue revising diagnostic handling to simplify and generalize it, and improve related infra.
- Add a new -verify mode to the mlir-opt tool that allows writing test cases
   for optimization and other passes that produce diagnostics.
 - Refactor existing the -check-parser-errors flag to mlir-opt into a new
   -split-input-file option which is orthogonal to -verify.
 - Eliminate the special error hook the parser maintained and use the standard
   MLIRContext's one instead.
 - Enhance the default MLIRContext error reporter to print file/line/col of
   errors when it is available.
 - Add new createChecked() methods to the builder that create ops and invoke
   the verify hook on them, use this to detected unhandled code in the
   RaiseControlFlow pass.
 - Teach mlir-opt about expected-error @+, it previously only worked with @-

PiperOrigin-RevId: 211305770
2019-03-29 13:08:51 -07:00
Uday Bondhugula 0122a99cbb Affine expression analysis and simplification.
Outside of IR/
- simplify a MutableAffineMap by flattening the affine expressions
- add a simplify affine expression pass that uses this analysis
- update the FlatAffineConstraints API (to be used in the next CL)

In IR:
- add isMultipleOf and getKnownGCD for AffineExpr, and make the in-IR
  simplication of simplifyMod simpler and more powerful.
- rename the AffineExpr visitor methods to distinguish b/w visiting and
  walking, and to simplify API names based on context.

The next CL will use some of these for the loop unrolling/unroll-jam to make
the detection for the need of cleanup loop powerful/non-trivial.

A future CL will finally move this simplification to FlatAffineConstraints to
make it more powerful. For eg., currently, even if a mod expr appearing in a
part of the expression tree can't be simplified, the whole thing won't be
simplified.

PiperOrigin-RevId: 211012256
2019-03-29 13:07:44 -07:00
Uday Bondhugula e9fb4b492d Introduce loop unroll jam transformation.
- for test purposes, the unroll-jam pass unroll jams the first outermost loop.

While on this:
- fix StmtVisitor to allow overriding of function to iterate walk over children
  of a stmt.

PiperOrigin-RevId: 210644813
2019-03-29 13:07:30 -07:00
Chris Lattner acd5bd98d1 First steps towards TF/XLA control flow lowering: functional if lowering.
- Implement support for the TensorFlow 'If' op, the first TF op definition.
 - Fill in some missing basic infra, including the ability to split a basic block, the ability to create a branch with operands, etc.
 - Implement basic lowering for some simple forms of If, where the condition is a zero-D bool tensor and when all the types line up.  Future patches will generalize this.

There is still much to be done here.  I'd like to get some example graphs coming from the converter to play with to direct this work.

PiperOrigin-RevId: 210198760
2019-03-29 13:05:01 -07:00
Uday Bondhugula 00bed4bd99 Extend loop unrolling to unroll by a given factor; add builder for affine
apply op.

- add builder for AffineApplyOp (first one for an operation that has
  non-zero operands)
- add support for loop unrolling by a given factor; uses the affine apply op
  builder.

While on this, change 'step' of ForStmt to be 'unsigned' instead of
AffineConstantExpr *. Add setters for ForStmt lb, ub, step.

Sample Input:

// CHECK-LABEL: mlfunc @loop_nest_unroll_cleanup() {
mlfunc @loop_nest_unroll_cleanup() {
  for %i = 1 to 100 {
    for %j = 0 to 17 {
      %x = "addi32"(%j, %j) : (affineint, affineint) -> i32
      %y = "addi32"(%x, %x) : (i32, i32) -> i32
    }
  }
  return
}

Output:

$ mlir-opt -loop-unroll -unroll-factor=4 /tmp/single2.mlir
#map0 = (d0) -> (d0 + 1)
#map1 = (d0) -> (d0 + 2)
#map2 = (d0) -> (d0 + 3)
mlfunc @loop_nest_unroll_cleanup() {
  for %i0 = 1 to 100 {
    for %i1 = 0 to 17 step 4 {
      %0 = "addi32"(%i1, %i1) : (affineint, affineint) -> i32
      %1 = "addi32"(%0, %0) : (i32, i32) -> i32
      %2 = affine_apply #map0(%i1)
      %3 = "addi32"(%2, %2) : (affineint, affineint) -> i32
      %4 = affine_apply #map1(%i1)
      %5 = "addi32"(%4, %4) : (affineint, affineint) -> i32
      %6 = affine_apply #map2(%i1)
      %7 = "addi32"(%6, %6) : (affineint, affineint) -> i32
    }
    for %i2 = 16 to 17 {
      %8 = "addi32"(%i2, %i2) : (affineint, affineint) -> i32
      %9 = "addi32"(%8, %8) : (i32, i32) -> i32
    }
  }
  return
}

PiperOrigin-RevId: 209676220
2019-03-29 13:03:38 -07:00
Chris Lattner d9290db5fe Finish support for function attributes, and improve lots of things:
- Have the parser rewrite forward references to their resolved values at the
   end of parsing.
 - Implement verifier support for detecting malformed function attrs.
 - Add efficient query for (in general, recursive) attributes to tell if they
   contain a function.

As part of this, improve other general infrastructure:
 - Implement support for verifying OperationStmt's in ml functions, refactoring
   and generalizing support for operations in the verifier.
 - Refactor location handling code in mlir-opt to have the non-error expecting
   form of mlir-opt invocations to report error locations precisely.
 - Fix parser to detect verifier failures and report them through errorReporter
   instead of printing the error and crashing.

This regresses the location info for verifier errors in the parser that were
previously ascribed to the function.  This will get resolved in future patches
by adding support for function attributes, which we can use to manage location
information.

PiperOrigin-RevId: 209600980
2019-03-29 13:03:11 -07:00
Jacques Pienaar ec1cfe2268 [mlir-opt] Enable defining which operations are defined at link time.
Previously mlir-opt had initializeMLIRContext function that added certain ops to the OperationSet of the context. But for different tests we'd want to register different ops. Make initializeMLIRContext an extern function so that the context initialization/set of ops to register can be determined at link time. This allows out-of-tree operations to easily expand the custom parsing/printing while still using mlir-opt.

PiperOrigin-RevId: 209078315
2019-03-29 13:01:47 -07:00
Uday Bondhugula 3e92be9c71 Move Pass.{h,cpp} from lib/IR/ to lib/Transforms/.
PiperOrigin-RevId: 208571437
2019-03-29 12:59:07 -07:00
Uday Bondhugula d8490d8d4f Loop unrolling pass update
- fix/complete forStmt cloning for unrolling to work for outer loops
- create IV const's only when needed
- test outer loop unrolling by creating a short trip count unroll pass for
  loops with trip counts <= <parameter>
- add unrolling test cases for multiple op results, outer loop unrolling
- fix/clean up StmtWalker class while on this
- switch unroll loop iterator values from i32 to affineint

PiperOrigin-RevId: 207645967
2019-03-29 12:56:16 -07:00
Chris Lattner ed9fa46413 Continue wiring up diagnostic reporting infrastructure, still WIP.
- Implement a diagnostic hook in one of the paths in mlir-opt which
   captures and reports the diagnostics nicely.
 - Have the parser capture simple location information from the parser
   indicating where each op came from in the source .mlir file.
 - Add a verifyDominance() method to MLFuncVerifier to demo this, resolving b/112086163
 - Add some PrettyStackTrace handlers to make crashes in the testsuite easier
   to track down.

PiperOrigin-RevId: 207488548
2019-03-29 12:55:34 -07:00
MLIR Team fe7356c43b Internal change
PiperOrigin-RevId: 206652744
2019-03-29 12:49:23 -07:00
Chris Lattner 782c348c00 Change mlir-opt.cpp to take a list of passes to run, simplifying the driver
code.  Change printing of affine map's to not print a space between the dim and
symbol list.

PiperOrigin-RevId: 206505419
2019-03-29 12:47:38 -07:00
Chris Lattner 12adbeb872 Prepare for implementation of TensorFlow passes:
- Sketch out a TensorFlow/IR directory that will hold op definitions and common TF support logic.  We will eventually have TensorFlow/TF2HLO, TensorFlow/Grappler, TensorFlow/TFLite, etc.
 - Add sketches of a Switch/Merge op definition, including some missing stuff like the TwoResults trait.  Add a skeleton of a pass to raise this form.
 - Beef up the Pass/FunctionPass definitions slightly, moving the common code out of LoopUnroll.cpp into a new IR/Pass.cpp file.
 - Switch ConvertToCFG.cpp to be a ModulePass.
 - Allow _ to start bare identifiers, since this is important for TF attributes.

PiperOrigin-RevId: 206502517
2019-03-29 12:47:25 -07:00
Uday Bondhugula a0abd666a7 Sketch out loop unrolling transformation.
- Implement a full loop unroll for innermost loops.
- Use it to implement a pass that unroll all the innermost loops of all
  mlfunction's in a module. ForStmt's parsed currently have constant trip
  counts (and constant loop bounds).
- Implement StmtVisitor based (Visitor pattern)

Loop IVs aren't currently parsed and represented as SSA values. Replacing uses
of loop IVs in unrolled bodies is thus a TODO. Class comments are sparse at some places - will add them after one round of comments.

A cmd-line flag triggers this for now.

Original:

mlfunc @loops() {
  for x = 1 to 100 step 2 {
    for x = 1 to 4 {
      "Const"(){value: 1} : () -> ()
    }
  }
  return
}

After unrolling:

mlfunc @loops() {
  for x = 1 to 100 step 2 {
    "Const"(){value: 1} : () -> ()
    "Const"(){value: 1} : () -> ()
    "Const"(){value: 1} : () -> ()
    "Const"(){value: 1} : () -> ()
  }
  return
}

PiperOrigin-RevId: 205933235
2019-03-29 12:43:01 -07:00
Tatiana Shpeisman 1b24c48b91 Scaffolding for convertToCFG pass that replaces all instances of ML functions with equivalent CFG functions. Traverses module MLIR, generates CFG functions (empty for now) and removes ML functions. Adds Transforms library and tests.
PiperOrigin-RevId: 205848367
2019-03-29 12:41:15 -07:00
James Molloy 4144c302db [mlir] Add basic block arguments
This patch adds support for basic block arguments including parsing and printing.

In doing so noticed that `ssa-id-and-type` is undefined in the MLIR spec; suggested an implementation in the spec doc.

PiperOrigin-RevId: 205593369
2019-03-29 12:38:20 -07:00
Jacques Pienaar c90de70329 Expand check-parser-errors to match multiple errrors per line.
* check-parser-errors can match multiple errors per line;
* Add offset notation to expected-error;

PiperOrigin-RevId: 203625348
2019-03-29 12:30:35 -07:00
Jacques Pienaar 2057b454dc Add default error reporter for parser.
Add a default error reporter for the parser that uses the SourceManager to print the error. Also and OptResult enum (mirroring ParseResult) to make the behavior self-documenting.

PiperOrigin-RevId: 203173647
2019-03-29 12:27:57 -07:00
Jacques Pienaar c7fe8c38a5 Report parsing error check failures wrt file being parsed.
For checking parse errors, the input file is split and failures reported per memory buffer. Simply reporting the errors loses the mapping back to the original file. Change the reporting to instead relate the error reported back to the original file.

Use SourceMgr's PrintMessage consistently for errors and relates back to file being parsed.

PiperOrigin-RevId: 202136152
2019-03-29 12:26:16 -07:00
Jacques Pienaar 39a33a2568 Change error verification of parser error checking.
Change from using FileCheck to directly verifying the message (simple substring checking) and line number of the error.

PiperOrigin-RevId: 201955181
2019-03-29 12:26:02 -07:00
Jacques Pienaar b11a95350f Change Lexer and Parser to take diagnostic reporter function.
Add diagnostic reporter function to lexer/parser and use that from mlir-opt to report errors instead of having the lexer/parser print the errors.

PiperOrigin-RevId: 201892004
2019-03-29 12:25:48 -07:00
Jacques Pienaar a5fb2f47e1 Add negative parsing tests using mlir-opt.
Add parsing tests with errors. Follows direct path of splitting file into test groups (using a marker) and parsing each section individually. The expected errors are checked using FileCheck and parser error does not result in terminating parsing the rest of the file if check-parser-error.

This is an interim approach until refactoring lexer/parser.

PiperOrigin-RevId: 201867941
2019-03-29 12:25:23 -07:00
Chris Lattner 49795d166f Introduce IR support for MLIRContext, primitive types, function types, and
vector types.

tensors and memref types are still TODO, and would be a good starter project
for someone.

PiperOrigin-RevId: 201782748
2019-03-29 12:24:32 -07:00
Chris Lattner 9b9f7ff5d4 Implement enough of a lexer and parser for MLIR to parse extfunc's without
arguments.

PiperOrigin-RevId: 201706570
2019-03-29 12:24:05 -07:00
Chris Lattner 5fc587ecf8 Continue sketching out basic infrastructure, including an input and output
filename, and printing of trivial stuff.  There is no parser yet, so the
input file is ignored.

PiperOrigin-RevId: 201596916
2019-03-29 12:23:51 -07:00
Chris Lattner 9603f9fe35 Sketch out a new repository for the mlir project (go/mlir).
PiperOrigin-RevId: 201540159
2019-03-29 12:23:24 -07:00