Skip to content

Translate array drop glue using MIR#41917

Merged
bors merged 11 commits into
rust-lang:masterfrom
arielb1:mir-array
May 28, 2017
Merged

Translate array drop glue using MIR#41917
bors merged 11 commits into
rust-lang:masterfrom
arielb1:mir-array

Conversation

@arielb1

@arielb1 arielb1 commented May 11, 2017

Copy link
Copy Markdown
Contributor

I was a bit lazy here and used a usize-based index instead of a pointer iteration. Do you think this is important @eddyb?

r? @eddyb

@eddyb

eddyb commented May 11, 2017

Copy link
Copy Markdown
Contributor

Can you check the optimized IR? Ideally we'd even have a test - I believe LLVM will turn it into a pointer loop.

Comment thread src/librustc/ty/util.rs Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't this usize be a u64 to be correct when compiling from 32 bit to 64?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In practice val is either 0 or 1.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see, it's probably ok then (still, it'd be nice to prevent misuses of this function)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

u16 is probably a good option for the type then, so one can never pass a value too large.

@alexcrichton alexcrichton added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label May 11, 2017

@nagisa nagisa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A few nits. I only skimmed translator changes, nothing obviously wrong there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NIT: Unreachable here would make it much more obvious this terminator is patched out a bit later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NIT: s/len/index/?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it guaranteed that is_cleanup is always false here? IIRC all the details related to this, it is guaranteed, in which this is_cleanup flag is redundant (unwind being None or Some already carries that information).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

is_cleanup is technically always false here because this can't be reached from "normal" drop elaboration, but if we fixed drop glue for arrays it would be true.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto here wrt usize/u16.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm worried about this code repeating itself for all used array lengths - would it be possible to have the array drop coerce to a *[T] and drop that? Or is thst premature optimization?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The code in question is fairly compact. I feel like LLVM would inline it in all cases anyway. The only really troublesome case I can imagine is somebody having a very large number of small arrays on stack.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was more worried about us instantiating so many copies of pretty much identical IR. But thinking more about it, various lengths of fixed-length arrays are somewhat rare in practice, so this might not be a problem at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I expect LLVM to always inline this anyway. Note that this is translated inline today.

@arielb1

arielb1 commented May 12, 2017

Copy link
Copy Markdown
Contributor Author

Can you check the optimized IR? Ideally we'd even have a test - I believe LLVM will turn it into a pointer loop.

Nope it doesn't. I'll try to write up pointer loops tomorrow.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The issue noted in the FIXME (#6393) is closed... should it be changed to a different issue? This is also the case in a few other places in the code.

@nagisa nagisa May 15, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can still easily track where to look from the comments in the issue (i.e. the niko’s in favour comment).

EDIT: nice trick. Amusing.

@nagisa

nagisa commented May 15, 2017

Copy link
Copy Markdown
Member

There’s some travis failures due to MIR variants being boxed now, @arielb1. You might want to rebase.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: iter::once(succ) is a more compact way to express this.

@nagisa

nagisa commented May 15, 2017

Copy link
Copy Markdown
Member

The last commit looks good.

@arielb1 arielb1 force-pushed the mir-array branch 2 times, most recently from 42e03a2 to 1d9c6d2 Compare May 15, 2017 15:56
@alexcrichton

Copy link
Copy Markdown
Member

@arielb1 is this waiting on review now? I couldn't immediately tell from the state of the PR. Just curious for what tags too apply!

@arielb1

arielb1 commented May 18, 2017

Copy link
Copy Markdown
Contributor Author

@alexcrichton

I'm trying to see whether I can get pointer-based iteration to work out nicely enough I'll want to use it.

@nagisa

nagisa commented May 20, 2017

Copy link
Copy Markdown
Member

I feel like code could be a bit more clear if the index-based loop and the pointer-based loop were separate, rather than so closely intermingled in the same function.

It is also not entirely clear to me that both BinOp::Offset and NullaryOp::SizeOf are necessary. That is, the Offset could be just a Add(x, SizeOf::<T>()).

These are the nits, feel free to ignore them.


Now… I think it could be possible to avoid indexing the array altogether in the loop. That is, instead of generating:

    /// loop-block:
    ///    can_go = index_or_cur == length_or_end
    ///    if can_go then succ else drop-block
    /// drop-block:
    ///    if size_of::<T> != 0 {
    ///        ptr = index_or_cur
    ///        index_or_cur = index_or_cur + size_of::<T>()
    ///    } else {
    ///        ptr = &mut LV[index_or_cur]
    ///        index_or_cur = index_or_cur + 1
    ///    }
    ///    drop(ptr);

It could be simplified(?) to this instead:

drop_selector:
    ptr = &mut LV[0];
    index = 0;
    len = len(LV);
    is_zero_sized = size_of::<T>() == 0;
    if is_zero_sized then zs_head else loop_head;
zs_head:
    finished = index == len;
    if finished then succ else zs_body;
zs_body:
    drop(ptr);
    index = index + 1;
    goto zs_head;
loop_head:
    finished = ptr == end;
    if finished then succ else loop_body
loop_body:
    drop(ptr);
    ptr = ptr + size_of::<T>();
    goto loop_head;

note the lack of actual “indexing” in the zero-sized case, which could plausibly make it easier for LLVM to optimise/unroll/etc the loop.

I was actually going to propose just using ptr as a index here – dereferencing a ZST is a no-op and therefore it doesn’t really matter what the pointer is, but then refrained because it is most likely UB.

It would also be worthwhile to have a FIXME somewhere to make SizeOf const-evaluated when possible, so SimplifyCfg could easily get rid of the other loop.

@arielb1

arielb1 commented May 21, 2017

Copy link
Copy Markdown
Contributor Author

That is, the Offset could be just a Add(x, SizeOf::<T>()).

Can you do an add with LLVM pointers? Plus, I want to emit a getelementptr inbounds.

@arielb1 arielb1 force-pushed the mir-array branch 2 times, most recently from c8478fc to e99766b Compare May 23, 2017 17:58
@arielb1

arielb1 commented May 23, 2017

Copy link
Copy Markdown
Contributor Author

this should fix the segfault

Comment thread src/librustc_trans/mir/block.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You added a method (funclet_bb) to CleanupKind that does this, shouldn't we just call it here? Unless I'm missing some detail.

@arielb1 arielb1 May 23, 2017

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

umm yeah. fixed

@nagisa

nagisa commented May 24, 2017

Copy link
Copy Markdown
Member

LGTM. I asked on IRC:

eddyb, I believe you asked for a codegen test for the arielby’s array dropping PR. Do you still want one given that the PR now uses the pointer loop when possible?

but got no response. Feel free to r- if you feel like one is still necessary.

@bors r+

@bors

bors commented May 24, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 9bfe40e has been approved by nagisa

@eddyb

eddyb commented May 25, 2017

Copy link
Copy Markdown
Contributor

I replied to both @nagisa and @arielb1 but on IRC it's easy to miss a message 😆.
There is no test necessary as my point was specifically about LLVM's optimization ability.

@bors

bors commented May 25, 2017

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 9bfe40e with merge 8889b73...

@rust-highfive rust-highfive assigned nagisa and unassigned eddyb May 27, 2017

@nagisa nagisa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two minor nits. Looks great otherwise. r=me.

I won’t be able to look at github for a few upcoming days and won’t be able to instruct bors either.

Comment thread src/librustc_trans/mir/mod.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You could create this builder outside the loop, avoiding an allocation and deallocation for each iteration, I think?

Comment thread src/librustc_trans/mir/block.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could use a better name. Something like cleanup_adjusted_llblock maybe? lltarget_inner or lltarget_common could also work.

@arielb1

arielb1 commented May 28, 2017

Copy link
Copy Markdown
Contributor Author

@bors r=nagisa

@bors

bors commented May 28, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 94f65c5 has been approved by nagisa

@arielb1

arielb1 commented May 28, 2017

Copy link
Copy Markdown
Contributor Author

@bors r=nagisa

@bors

bors commented May 28, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit 137e710 has been approved by nagisa

@arielb1

arielb1 commented May 28, 2017

Copy link
Copy Markdown
Contributor Author

@bors r=nagisa

@bors

bors commented May 28, 2017

Copy link
Copy Markdown
Collaborator

📌 Commit ee982d4 has been approved by nagisa

@bors

bors commented May 28, 2017

Copy link
Copy Markdown
Collaborator

⌛ Testing commit ee982d4 with merge 924898f...

bors added a commit that referenced this pull request May 28, 2017
Translate array drop glue using MIR

I was a bit lazy here and used a usize-based index instead of a pointer iteration. Do you think this is important @eddyb?

r? @eddyb
@bors

bors commented May 28, 2017

Copy link
Copy Markdown
Collaborator

☀️ Test successful - status-appveyor, status-travis
Approved by: nagisa
Pushing 924898f to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants