This is an archive of the discontinued LLVM Phabricator instance.

[OPENMP] Initial codegen for 'omp task' directive.
ClosedPublic

Authored by ABataev on Feb 11 2015, 7:06 AM.

Details

Summary

The task region is emmitted in several steps:

  1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the function:
kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
  TaskFunction(gtid, tt->part_id, tt->shareds);
  return 0;
}
  1. Copy a list of shared variables to field shareds of the resulting structure kmp_task_t returned by the previous call (if any).
  2. Copy a pointer to destructions function to field destructions of the resulting structure kmp_task_t.
  3. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *new_task), where new_task is a resulting structure from previous items.

Diff Detail

Event Timeline

ABataev updated this revision to Diff 19752.Feb 11 2015, 7:06 AM
ABataev retitled this revision from to [OPENMP] Initial codegen for 'omp task' directive..
ABataev updated this object.
ABataev edited the test plan for this revision. (Show Details)
ABataev added a subscriber: Unknown Object (MLST).
rjmccall edited edge metadata.Feb 26 2015, 6:53 PM

Sorry for the delay.

In general, your code is very difficult to read; it doesn't use any vertical whitespace within functions at all, so I can't easily understand how things are supposed to be grouped.

The basic implementation seems fine, though I have a number of requests:

lib/CodeGen/CGOpenMPRuntime.cpp
118

Build this type lazily, please.

119

A better way of commenting the next few lines would be to just write the struct definition out and then put all the addFieldToRecordDecl calls together.

133

Build this type lazily, please.

252

It looks like the invariants about getThreadIDVariable have changed; it used to always be an int32*, and now it can be either that or an int32. EmitThreadIDAddress appears to still assume that it's an ident*. You should fix that and then add a test that the OpenMP constructs using that still work correctly within a task.

You should also document this on CGOpenMPRegionInfo::ThreadIDVar.

257

Missing braces.

1009

Somewhere around here would be a good place to put the code that lazily builds KmpTaskTRD.

1012

Comment, please. Please include the fact that this leaves the RecordDecl incomplete.

Also, RD has to be KmpTaskTRD, so remove that argument and make this take the CGOpenMPRuntime.

1093

Please add a newline after this comment to make it clear that it's describing the next sequence of steps as a whole.

lib/CodeGen/CGOpenMPRuntime.h
17

I don't think you need this; you can just forward-declare QualType. If you do need this, you can remove the forward-declaration of RecordDecl, I am positive that Type.h does that already.

288

I was concerned about awkwardly making a single function do completely different things based on weird defaulted parameter, but it turns out that those types are exactly the same.

Would it be more appropriate to say that this creates an outlined function, and that if PartID is given, it's bound to the appropriate parameter value?

Although it also looks like PartIDVar is completely ignored except for an assertion. Is that expected to change?

lib/Sema/SemaOpenMP.cpp
1124

This seems be hard-coding KMP runtime assumptions into Sema and the AST. Is that unavoidable?

John, thanks for the review!

lib/CodeGen/CGOpenMPRuntime.cpp
118

Ok

119

Ok

133

Ok

252

I'll fix it.

257

My bad, will be fixed

1012

Ok, I'll improve it

1093

Ok, will be done.

lib/CodeGen/CGOpenMPRuntime.h
17

I'll fix it.

288

I'll try to split this function in two - one for tasks and another one for parallel regions. I think this is better, rather than keep too complex single function.

lib/Sema/SemaOpenMP.cpp
1124

Unfortunately, no. I'm trying to avoid runtime assumptions in common code, but sometimes (like function parameters for outlined functions) I'm just forced to make some hard-coding of runtime specific features.

ABataev updated this revision to Diff 20986.Mar 2 2015, 1:33 AM
ABataev edited edge metadata.

Update after review

Sorry for the delay. Phabricator's been acting up; you'll notice a couple of comments that I wasn't able to delete, because deleting them locked the webpage up and never applied the deletion. Hooray for tools.

Generally looking better.

lib/CodeGen/CGOpenMPRuntime.cpp
45

Okay. I think I see what you've done here with the subclass, so that this always produces a ident_t l-value, and thus its address is always an ident_t*. That makes a lot of sense to me. Please document that.

73

.

73

.

77

.

152

This is a great assertion, thanks.

983

*Indexes* of fields in type kmp_task_t.

1045

Closing parenthesis. Also, I'd make a getter for this instead of inlining it here.

1075

Argument comments are useful when somebody reading the code might not understand the purpose of the argument. In this case, that purpose is pretty obvious from the argument expression itself, so the comment is useless.

1111

It's generally better to emit helper functions in a separate function, so that any particular function only knows about one CodeGenFunction object:

  • It removes some code from what's already a pretty large function.
  • It makes the shared data between the two functions a lot more obvious.
  • It removes any confusion about which function any particular llvm::Value* is valid in, so that you aren't tempted to (e.g.) use SharedsParam in the CGF function instead of the TaskEntryCGF function.
1147

You're probably going to need to ask Sema to generate a copy constructor expression to get this right in C++. Feel free to do that in a separate patch.

1163

Nothing cares about the result of this call?

lib/CodeGen/CGOpenMPRuntime.h
288

I'd write these as parameter names, i.e. void (*)(kmp_int32 *ThreadID, kip_int32 BoundID, struct context_vars*). The C-style comment right next to the * is really hard to read.

299

Same thing. Just write these comments as parameter names.

lib/CodeGen/CGStmtOpenMP.cpp
762

You don't need to comment obvious arguments like this (and like a few other places nearby). The reader understands what the purpose of the argument is, and "K=" doesn't add anything meaningful anyway.

771

Braces.

John, thanks for the review!

lib/CodeGen/CGOpenMPRuntime.cpp
45

Ok, will do

983

Ok, thanks.

1045

Ok, agree, that getter would look much better.

1075

Ok, removed

1111

Agree, I will create a separate function for proxy function

1147

I don't think I need to call a copy constructor here. Actually structure with a list of shared variables is always POD type (it stores only pointers and integer values), so we can simply copy it

1163

The check is required for untied tasks only, but they are not supported yet. I'll add TODO here.

lib/CodeGen/CGOpenMPRuntime.h
288

Fixed

299

Fixed

lib/CodeGen/CGStmtOpenMP.cpp
762

Ok, removed

771

Fixed

ABataev updated this revision to Diff 21551.Mar 10 2015, 12:15 AM

Update after review

Okay, if all the shareds are by-reference or something, that certainly simplifies things.

LGTM, thanks!

This revision was automatically updated to reflect the committed changes.