Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Op's create methods support passing an instruction name #80

Conversation

JanRehders-AMD
Copy link
Contributor

@JanRehders-AMD JanRehders-AMD commented Jan 30, 2024

Equivalent to CallInst, for more readable code. This allows to pass in a value name without a call to setName which is especially useful when directly returning a create op.

For example:

return m_builder->create<ExampleOp>(m_builder->getInt32(123), "example_123");

@JanRehders-AMD JanRehders-AMD marked this pull request as draft January 30, 2024 16:23
@JanRehders-AMD JanRehders-AMD marked this pull request as ready for review January 30, 2024 16:23
@JanRehders-AMD
Copy link
Contributor Author

@nhaehnle @Flakebi could you add yourself as reviewers? Didn't do that when creating the PR and don't have enough rights to add you later

@tsymalla
Copy link
Contributor

You need to update the generated files for the Example dialect for this to pass CI.

Copy link
Contributor

@tsymalla-AMD tsymalla-AMD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please do the following:

  • Update the tests
  • Show how this plays with an op argument called instName (we are doing some name mangling in case of duplicated arguments, correct @nhaehnle ?)
  • Add a test that shows how this plays with variadic arguments?

@nhaehnle
Copy link
Member

As @tsymalla-AMD pointed out, you do need to fix the CI failures here.

@tsymalla
Copy link
Contributor

As @tsymalla-AMD pointed out, you do need to fix the CI failures here.

You just need to take the ExampleDialect.h.inc and ExampleDialect.cpp.inc, which should be generated as part of the check-llvm-dialects target, and put it in the generated/ folder for the CI to pass.

@JanRehders-AMD JanRehders-AMD force-pushed the amd/dev/jrehders/create-op-with-name branch from fe5bfe4 to b67d69d Compare January 31, 2024 11:44
@tsymalla
Copy link
Contributor

Please add some tests (as mentioned above) that shows the name of the instruction is correctly set, and that this plays correctly with various cases. Thanks.

@JanRehders-AMD JanRehders-AMD force-pushed the amd/dev/jrehders/create-op-with-name branch 2 times, most recently from a71e8ed to ddffa5c Compare January 31, 2024 12:20
@JanRehders-AMD
Copy link
Contributor Author

@tsymalla There was indeed a naming conflict causing this to not compile. I've added a fix for that (separate commit so it's easier to review but will be squashed) plus a test.

Here is the code produced by the conflict test I've added:

class InstNameConflictTestOp : public ::llvm::CallInst {
  static const ::llvm::StringLiteral s_name; //{"test.try.conflict"};

public:
  static bool classof(const ::llvm::CallInst *i) {
    return ::llvm_dialects::detail::isSimpleOperation(i, s_name);
  }
  static bool classof(const ::llvm::Value *v) {
    return ::llvm::isa<::llvm::CallInst>(v) &&
           classof(::llvm::cast<::llvm::CallInst>(v));
  }
  static InstNameConflictTestOp *create(::llvm_dialects::Builder &b,
                                        ::llvm::Value *instName,
                                        ::llvm::Value *inst_Name,
                                        const llvm::Twine &inst__name = "");

  bool verifier(::llvm::raw_ostream &errs);

  ::llvm::Value *getInstName();
  void setInstName(::llvm::Value *instName);
  ::llvm::Value *getInst_Name();
  void setInst_Name(::llvm::Value *inst__name);
};

and from the test single-vararg.td:

class SingleVarArgOp : public ::llvm::CallInst {
  static const ::llvm::StringLiteral s_name; //{"test.return"};

public:
  static bool classof(const ::llvm::CallInst *i) { return ::llvm_dialects::detail::isSimpleOperation(i, s_name); }
  static bool classof(const ::llvm::Value *v) {
    return ::llvm::isa<::llvm::CallInst>(v) && classof(::llvm::cast<::llvm::CallInst>(v));
  }
  static SingleVarArgOp *create(::llvm_dialects::Builder &b, ::llvm::ArrayRef<::llvm::Value *> args,
                                const llvm::Twine &inst__name = "");

  bool verifier(::llvm::raw_ostream &errs);

  ::llvm::iterator_range<::llvm::User::value_op_iterator> getArgs();
};

Copy link
Member

@nhaehnle nhaehnle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM, but please do extend test-builder.test (and ExampleMain.cpp) with a test for this.

@tsymalla-AMD
Copy link
Contributor

LGTM (you need to resolve the merge conflict)

example/ExampleDialect.td Outdated Show resolved Hide resolved
@JanRehders-AMD
Copy link
Contributor Author

Please add some tests (as mentioned above) that shows the name of the instruction is correctly set, and that this plays correctly with various cases. Thanks.

From MainExample.cpp

  b.create<xd::HandleGetOp>("name.of.llvm.value");
  b.create<xd::InstNameConflictOp>(b.getInt32(1));
  b.create<xd::InstNameConflictOp>(b.getInt32(1), "name.foo");
  b.create<xd::InstNameConflictDoubleOp>(b.getInt32(1), b.getInt32(2));
  b.create<xd::InstNameConflictDoubleOp>(b.getInt32(1), b.getInt32(2), "bar");
  SmallVector<Value *> moreVarArgs = varArgs;
  b.create<xd::InstNameConflictVarargsOp>(moreVarArgs);
  b.create<xd::InstNameConflictVarargsOp>(moreVarArgs, "two.varargs");
  moreVarArgs.push_back(b.getInt32(3));
  b.create<xd::InstNameConflictVarargsOp>(moreVarArgs, "three.varargs");
  moreVarArgs.push_back(b.getInt32(4));
  b.create<xd::InstNameConflictVarargsOp>(moreVarArgs, "four.varargs");

produces

  %name.of.llvm.value = call target("xd.handle") @xd.handle.get()
  %19 = call i32 (...) @xd.inst.name.conflict(i32 1)
  %name.foo = call i32 (...) @xd.inst.name.conflict(i32 1)
  %20 = call i32 (...) @xd.inst.name.conflict.double(i32 1, i32 2)
  %bar = call i32 (...) @xd.inst.name.conflict.double(i32 1, i32 2)
  %21 = call i32 (...) @xd.inst.name.conflict.varargs(ptr %p1, i8 %p2)
  %two.varargs = call i32 (...) @xd.inst.name.conflict.varargs(ptr %p1, i8 %p2)
  %three.varargs = call i32 (...) @xd.inst.name.conflict.varargs(ptr %p1, i8 %p2, i32 3)
  %four.varargs = call i32 (...) @xd.inst.name.conflict.varargs(ptr %p1, i8 %p2, i32 3, i32 4)
  ret void

Equivalent to CallInst, for more readable code. This allows to pass in a value
name without a call to setName which is especially useful when directly
returning a create op.

For example:

  return m_builder->create<ExampleOp>(m_builder->getInt32(123), "example_123");
Naming the parameter inst__name. If an op has an argument with that name it will
be normalized into inst_Name which does not conflict.
@JanRehders-AMD JanRehders-AMD force-pushed the amd/dev/jrehders/create-op-with-name branch from 7f0f151 to e58659e Compare February 1, 2024 18:49
@tsymalla-AMD tsymalla-AMD merged commit 3f9e17f into GPUOpen-Drivers:dev Feb 2, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants