profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/lattner/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

apple/swift 57343

The Swift Programming Language

apple/swift-evolution 12742

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.

llvm/llvm-project 10426

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Note: the repository does not accept github pull requests at this moment. Please submit your patches at http://reviews.llvm.org.

apple/swift-package-manager 8501

The Package Manager for the Swift Programming Language

apple/swift-corelibs-foundation 4409

The Foundation Project, providing core utilities, internationalization, and OS independence

apple/swift-corelibs-libdispatch 2108

The libdispatch Project, (a.k.a. Grand Central Dispatch), for concurrency on multicore hardware

apple/swift-corelibs-xctest 931

The XCTest Project, A Swift core library for providing unit test support

apple/swift-llbuild 890

A low-level build system, used by Xcode and the Swift Package Manager

llvm/circt 693

Circuit IR Compilers and Tools

issue commentllvm/circt

[HW] How to use default parameter

Right, you need to specify all the arguments at the instance site, the default arguments just causes the verilog emitter to omit them. I'll write up some rationale docs explaining the "why" behind this!

teqdruid

comment created time in 14 hours

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

 //===----------------------------------------------------------------------===//  /// An attribute to indicate the output file an operation should be emitted to.-def OutputFileAttr : StructAttr<"OutputFileAttr", HWDialect, [-  StructFieldAttr<"directory", OptionalAttr<StrAttr>>,-  StructFieldAttr<"name", OptionalAttr<StrAttr>>,-  StructFieldAttr<"exclude_from_filelist",-    DefaultValuedAttr<BoolAttr, "false">>,-  StructFieldAttr<"exclude_replicated_ops",-    DefaultValuedAttr<BoolAttr, "true">>,-]>;+def OutputFileAttr : AttrDef<HWDialect, "OutputFile"> {+  let summary = "Ouput file attribute";+  let description = [{+    This attribute represents an output file for something which will be+    printed. The `filename` string is the file to be output to. If `filename`+    ends in a `/` it is considered an output directory.++    When creating an `OutputFileAttr` the `name` and `directory` should be+    normalized, with uneeded indirection to the target file removed.  This is+    so that `OutputFileAttrs` which are pointing at the same file will be+    equivalent. The `getWithFilename` function will properly handle this+    process.++    When ExportVerilog runs, one of the files produced is a list of all other+    files which are produced. The flag `excludeFromFileList` controls if this+    file should be included in this list. If any `OutputFileAttr` referring to+    the same file sets this to `true`, it will be included in the file list.+    This option defaults to `false`.++    For each file emitted by the verilog emitter, certain prelude output will+    be included before the main content. The flag `includeReplicatedOps` can+    be used to disable the addition of the prelude text. All `OutputFileAttr`s+    referring to the same file must use a consistent setting for this value.+    This option defaults to `true`.++    Examples:+    ```mlir+      #hw.ouput_file<"/home/tester/t.sv">+      #hw.ouput_file<"t.sv", excludeFromFileList, includeReplicatedOps>+    ```+  }];+  let mnemonic = "output_file";+  let parameters = (ins "::mlir::StringAttr":$filename,+                        "::mlir::BoolAttr":$excludeFromFilelist,+                        "::mlir::BoolAttr":$includeReplicatedOps);+  let builders = [+    AttrBuilderWithInferredContext<(ins+                                   "::mlir::StringAttr":$filename,+                                   "::mlir::BoolAttr":$excludeFromFileList,+                                   "::mlir::BoolAttr":$includeReplicatedOps), [{+      return get(filename.getContext(), filename, excludeFromFileList,+                 includeReplicatedOps);+    }]>,+  ];++  let extraClassDeclaration = [{+    /// Get an OutputFileAttr from a string filename, canonicalizing the+    /// filename.  +    static OutputFileAttr getFromFilename(::mlir::MLIRContext *context,+                                          const ::mlir::Twine &filename,+                                          bool excludeFromFileList = false,+                                          bool includeReplicatedOps = false);++    /// Get an OutputFileAttr from a string filename, resolving it relative to+    /// `directory`. If `filename` is an absolute path, the given `directory`+    /// will not be used.+    static OutputFileAttr getFromDirectoryAndFilename(+                                          ::mlir::MLIRContext *context,+                                          const ::mlir::Twine &directory,+                                          const ::mlir::Twine &filename,+                                          bool excludeFromFileList = false,+                                          bool includeReplicatedOps = false);

How about dropping some default arguments?

youngar

comment created time in 14 hours

PullRequestReviewEvent

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

 hw.module @signed_arrays(%arg0: si8) -> (out: !hw.array<2xsi8>) { // CHECK-LABEL: hw.module @argRenames // CHECK-SAME: attributes {argNames = [""]} hw.module @argRenames(%arg1: i32) attributes {argNames = [""]} {-}\ No newline at end of file+}+++// CHECK-LABEL: OutputFileAttr+hw.module @OutputFileAttr() -> () attributes {tests = [+  // CHECK-SAME: #hw.output_file<"", "test0.sv">+  #hw.output_file<"", "test0.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test1.sv">,+  #hw.output_file<"dir", "test1.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test2.sv">+  #hw.output_file<"", "dir/test2.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test3.sv">+  #hw.output_file<"/dir/", "test3.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test4.sv">+  #hw.output_file<"x", "/dir/test4.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test5.sv">+  #hw.output_file<"", "/dir/test5.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test6.sv">+  #hw.output_file<"./x/x/./../..", "dir/./x/../test6.sv">,++  // CHECK-SAME: #hw.output_file<"/", "">+  #hw.output_file<"/", "">,++  // CHECK-SAME: #hw.output_file<"/", "">+  #hw.output_file<".", "/">,++  // CHECK-SAME: #hw.output_file<"", "test.sv", excludeFromFileList, includeReplicatedOps>+  #hw.output_file<"", "test.sv", excludeFromFileList, includeReplicatedOps>

IR's are good for that! That also allows you to have some nice "isDirectory()" methods etc.

youngar

comment created time in 19 hours

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

 //===----------------------------------------------------------------------===//  /// An attribute to indicate the output file an operation should be emitted to.-def OutputFileAttr : StructAttr<"OutputFileAttr", HWDialect, [-  StructFieldAttr<"directory", OptionalAttr<StrAttr>>,-  StructFieldAttr<"name", OptionalAttr<StrAttr>>,-  StructFieldAttr<"exclude_from_filelist",-    DefaultValuedAttr<BoolAttr, "false">>,-  StructFieldAttr<"exclude_replicated_ops",-    DefaultValuedAttr<BoolAttr, "true">>,-]>;+def OutputFileAttr : AttrDef<HWDialect, "OutputFile"> {+  let summary = "Ouput file attribute";+  let description = [{+    This attribute represents an output file for something which will be+    printed.++    The `directory` string is the name of output directory. If the `directory`+    is empty, it will be output to the current working directory.++    The `filename` string is the file to be output to. This name should not+    contain any `/` characters.  If the `filename` is empty, then this+    attribute represents an output directory.++    When creating an `OutputFileAttr` the `name` and `directory` should be+    canonicalized, with uneeded indirection to the target file removed.  This+    is so that `OutputFileAttrs` which are pointing at the same file will be+    equivalent. The `getWithFilename` functions properly handle this process,+    and accept a full path for a `filename` and will attempt to resolve it+    using `directory` as the starting point.++    When ExportVerilog runs, one of the files produced is a list of all other+    files which are produced. The flag `excludeFromFileList` controls if this+    file should be included in this list. If any `OutputFileAttr` referring to+    the same file sets this to `true`, it will be included in the file list.+    This option defaults to `false`.++    For each file emitted by the verilog emitter, certain prelude output will+    be included before the main content. The flag `includeReplicatedOps` can+    be used to disable the addition of the prelude text. All `OutputFileAttr`s+    referring to the same file must use a consistent setting for this value.+    This option defaults to `true`. ++    Examples:+    ```mlir+      #hw.ouput_file<"/home/tester/t.sv">+      #hw.ouput_file<"t.sv", excludeFromFileList, includeReplicatedOps>+    ```+  }];+  let mnemonic = "output_file";+  let parameters = (ins "::mlir::StringAttr":$directory,+                        "::mlir::StringAttr":$name,+                        "::mlir::BoolAttr":$excludeFromFilelist,+                        "::mlir::BoolAttr":$includeReplicatedOps);+  let builders = [+    AttrBuilderWithInferredContext<(ins+                                  "::mlir::StringAttr":$directory,+                                  "::mlir::StringAttr":$name,+                                  "::mlir::BoolAttr":$excludeFromFileList,+                                  "::mlir::BoolAttr":$includeReplicatedOps), [{+      return get(directory.getContext(), directory, name, excludeFromFileList, +                 includeReplicatedOps);+    }]>,++    AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$directory,+                                        "::mlir::StringAttr":$name), [{+      auto *context = directory.getContext();+      return get(context, directory, name, BoolAttr::get(context, false),+                 BoolAttr::get(context, false));+    }]>+  ];++  let extraClassDeclaration = [{+    /// Get an OutputFileAttr from a string filename, canonicalizing the+    /// filename.  This will properly populate the `directory` and `name`+    /// attributes of the created `OutputFileAttr`.+    static OutputFileAttr getFromFilename(::mlir::MLIRContext *context,+                                          ::mlir::StringRef filename,+                                          bool excludeFromFileList = false,+                                          bool includeReplicatedOps = false);++    /// Get an OutputFileAttr from a string filename, resolving it relative to+    /// `directory`. If `fileanme` is an absolute path, the given `directory`+    /// will not be used.+    static OutputFileAttr getFromFilename(::mlir::MLIRContext *context,+                                          ::mlir::StringRef workingDirectory,+                                          ::mlir::StringRef filename,+                                          bool excludeFromFileList = false,+                                          bool includeReplicatedOps = false);+  }];++//    StructFieldAttr<"directory", OptionalAttr<StrAttr>>,+//    StructFieldAttr<"name", OptionalAttr<StrAttr>>,+//    StructFieldAttr<"exclude_from_filelist",+//      DefaultValuedAttr<BoolAttr, "false">>,+//    StructFieldAttr<"exclude_replicated_ops",+//      DefaultValuedAttr<BoolAttr, "true">>,+//  ]> {

Plz drop the commented out code.

youngar

comment created time in 21 hours

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

 add_circt_dialect_library(CIRCTHW    DEPENDS   MLIRHWIncGen+  MLIRHWAttrIncGen+  MLIRHWStructsIncGen

MLIRHWStructsIncGen can this be dropped?

youngar

comment created time in 19 hours

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

 hw.module @signed_arrays(%arg0: si8) -> (out: !hw.array<2xsi8>) { // CHECK-LABEL: hw.module @argRenames // CHECK-SAME: attributes {argNames = [""]} hw.module @argRenames(%arg1: i32) attributes {argNames = [""]} {-}\ No newline at end of file+}+++// CHECK-LABEL: OutputFileAttr+hw.module @OutputFileAttr() -> () attributes {tests = [+  // CHECK-SAME: #hw.output_file<"", "test0.sv">+  #hw.output_file<"", "test0.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test1.sv">,+  #hw.output_file<"dir", "test1.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test2.sv">+  #hw.output_file<"", "dir/test2.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test3.sv">+  #hw.output_file<"/dir/", "test3.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test4.sv">+  #hw.output_file<"x", "/dir/test4.sv">,++  // CHECK-SAME: #hw.output_file<"/dir", "test5.sv">+  #hw.output_file<"", "/dir/test5.sv">,++  // CHECK-SAME: #hw.output_file<"dir", "test6.sv">+  #hw.output_file<"./x/x/./../..", "dir/./x/../test6.sv">,++  // CHECK-SAME: #hw.output_file<"/", "">+  #hw.output_file<"/", "">,++  // CHECK-SAME: #hw.output_file<"/", "">+  #hw.output_file<".", "/">,++  // CHECK-SAME: #hw.output_file<"", "test.sv", excludeFromFileList, includeReplicatedOps>+  #hw.output_file<"", "test.sv", excludeFromFileList, includeReplicatedOps>

I agree that having the parser normalize is a bit weird. Instead of storing the fields separately, is there any downside to storing them together?

youngar

comment created time in 19 hours

PullRequestReviewEvent

Pull request review commentllvm/circt

[HW] Add OutputFileAttr helper

  // Pull in all enum type definitions and utility function declarations. #include "circt/Dialect/HW/HWEnums.h.inc"-#include "circt/Dialect/HW/HWStructs.h.inc"

Can any cmake support for building HWStructs be dropped?

youngar

comment created time in 19 hours

CommitCommentEvent

pull request commentllvm/circt

[Python] Fix Python Bindings

Thank you both, I appreciate the help with this.

teqdruid

comment created time in a day

issue closedllvm/circt

[HW] ParamDeclAttr printer aborts

https://github.com/llvm/circt/blob/4379fab383edf6da8bb86d04ae6a41970e620b9f/lib/Dialect/HW/HWAttributes.cpp#L61

This function gets called from the Python debugger and promptly crashes the debugger. In general, it's a bad idea to have side-effectful print functions since they can get called from anywhere -- especially when debugging. It needs to print something even if that something is that error message. The abort() is particularly heinous.

closed time in a day

teqdruid

issue commentllvm/circt

[HW] ParamDeclAttr printer aborts

Fixed in 3fd09246, thanks!

teqdruid

comment created time in a day

push eventllvm/circt

Chris Lattner

commit sha 3fd09246c36952aa68413dbc613806f2a76662cc

[HW] Add basic support for ParamDeclAttr::print. This isn't used in the normal IR printing, but can happen in debugging situations. This resolves Issue #1859.

view details

push time in a day

issue commentllvm/circt

[HW] ParamDeclAttr printer aborts

Good call, sorry I didn't know it caused a problem, thanks for letting me know will fix.

teqdruid

comment created time in a day

PullRequestReviewEvent

Pull request review commentllvm/circt

[Comb] Canonicalize mux with constant inputs

 LogicalResult MuxOp::canonicalize(MuxOp op, PatternRewriter &rewriter) {     }   } +  // When both inputs are constants, push the mux expression into each bit of+  // the inputs and attempt to fold each bitwise mux.+  // E.g. mux(a, 2, 0) -> concat(mux(a, 1, 0), 0) -> concat(a, 0)+  if (matchPattern(op.trueValue(), m_RConstant(value)) &&+      value.getBitWidth() > 1) {+    APInt value2;+    if (matchPattern(op.falseValue(), m_RConstant(value2))) {+      SmallVector<Value> operands;+      // Iterate from MSB to LSB, constructing a mux op on each bit.+      for (int64_t i = value.getBitWidth() - 1; i >= 0; --i) {+        auto trueValue =+            rewriter.createOrFold<ExtractOp>(op.getLoc(), op.trueValue(), i, 1);+        auto falseValue = rewriter.createOrFold<ExtractOp>(+            op.getLoc(), op.falseValue(), i, 1);+        operands.push_back(rewriter.createOrFold<comb::MuxOp>(+            op.getLoc(), op.cond(), trueValue, falseValue));+      }+      rewriter.replaceOpWithNewOp<ConcatOp>(op, op.getType(), operands);

Per your comment, I think we should start by only doing this when we aren't carving it up into too many pieces. How about we start with "exactly one bit different between the two constants"? You can check for this with something like (trueValue^falseValue).isPowerOfTwo().

Given that, your concat will always have two or three chunks - plz build it that way, instead of building it bitwise and relying on the concat to merge it back. This would save a lot of compile time, particularly with i128's or whatever.

richardxia

comment created time in 2 days

Pull request review commentllvm/circt

[Comb] Canonicalize mux with constant inputs

 LogicalResult MuxOp::canonicalize(MuxOp op, PatternRewriter &rewriter) {     }   } +  // When both inputs are constants, push the mux expression into each bit of+  // the inputs and attempt to fold each bitwise mux.+  // E.g. mux(a, 2, 0) -> concat(mux(a, 1, 0), 0) -> concat(a, 0)+  if (matchPattern(op.trueValue(), m_RConstant(value)) &&+      value.getBitWidth() > 1) {

Similar comment: please conserve matchPattern calls by merging these things together a bit.

richardxia

comment created time in 2 days

Pull request review commentllvm/circt

[Comb] Canonicalize mux with constant inputs

 static bool foldMuxChain(MuxOp rootMux, bool isFalseSide, LogicalResult MuxOp::canonicalize(MuxOp op, PatternRewriter &rewriter) {   APInt value; +  // mux(a, 0, 1) -> ~a for single-bit values.+  if (matchPattern(op.trueValue(), m_RConstant(value)) &&+      value.getBitWidth() == 1 && value.isZero()) {+    APInt value2;+    if (matchPattern(op.falseValue(), m_RConstant(value2)) &&+        value2.isAllOnes()) {+      auto one = rewriter.create<hw::ConstantOp>(op.getLoc(), APInt(1, 1));+      rewriter.replaceOpWithNewOp<XorOp>(op, op.cond(), one);+      return success();

This logic LGTM, but please merge it into the stuff below so the "trueValue" is only matched to a constant once. One additional tweak: can you reuse op.trueValue() (which you known is a single bit one value) rather than creating a new "one" constantop?

richardxia

comment created time in 2 days

PullRequestReviewEvent

pull request commentllvm/circt

[Comb] Canonicalize mux with constant inputs

This is really awesome, thank you for tackling this!

I wasn't sure if applying this transformation on all mux ops that have constant inputs was being too aggressive or too conservative, since I don't have a great sense of what is "simpler," so I was hoping to get some guidance here.

I agree, I think this is the crux of the question. This is the section of the rationale that we've started to discuss this, but as you say, we need to talk about this specific case more.

In my opinion, at the "HW" level of abstraction, we shouldn't drop to literally bit level modeling egregiously, even though it may open other simplifications. Such a thing will bloat the IR with lots of operations, and will slow down verilator and other things quite a bit.

The most conservative thing to do is to implement the general pass and then gate it with a bunch of heuristics in which it is "obviously good", such as when the simplification drops the mux condition into exactly one bit and the rest turns constant. This is moving complexity around, but not exploding the size of the IR.

I'll take a detailed look at your patch now.

richardxia

comment created time in 2 days

push eventllvm/circt

Chris Lattner

commit sha 738896e3ac9db67ebc760b2d32af01861e4c0044

[LowerAnnotations] Remove an unused function that was causing a warning, NFC. Also switch to more standard llvm comment dividers.

view details

push time in 2 days

push eventllvm/circt

Chris Lattner

commit sha 895d4239ff5e625c4bef79cc81b4210cf9cdac87

[tests] remove an incorrect requires line I accidentally added. Thanks to @youngar for noticing this!

view details

push time in 2 days

CommitCommentEvent

issue commentllvm/circt

[HW] Parameters step #3: Canonicalizing expression arithmetic

 // CHECK:      parameters2 #(
  // CHECK-NEXT:  .p1((xx + 42'd17) * yy)
  // CHECK-NEXT: ) inst3 (
  %c = hw.instance "inst3" @parameters2<p1: i42 = #hw.param.binary<mul #hw.param.binary<add #hw.param.verbatim<"xx">, 17>, #hw.param.verbatim<"yy">>, p2: i1 = 0>(arg0: %arg0: i8) -> (out: i8)
lattner

comment created time in 2 days

issue openedllvm/circt

[HW] Parameters step #4: Add support for "integer" verilog type

SystemVerilog supports typed integer parameters (e.g. 3 bits) but Verilog doesn't. We need to support plain old integer types for old verilog clients, this is also the most commonly used thing for type sizes etc.

created time in 2 days

issue openedllvm/circt

[HW] Parameters step #3: Canonicalizing expression arithmetic

We now support parameterized modules and simple expressions on those parameters. Before we get to using types in parameters, we need the parameter expressions to be stable, at least across an important subset of expressions. For example, when we have a parameterized integer type, we need to be able to do:

%0 = comb.concat %thing, %false, %thing2, %false : (i3, i1, !hw.int<param>, i1) -> !hw.int<param+5>

And the result type needs to be deterministic and stable. The first step to this is canonicalizing the param exprs in a predictable way. I recommend we focus on the affine expressions: multiply, add, and negate. The rewrites are very simple, and this enables the most obvious important things. We can expand this over time.

created time in 2 days

issue commentllvm/circt

[HW] Parameterized Modules, step #2

Simple +/* expressions are now supported. I'll file steps #3 and #4.

lattner

comment created time in 2 days