Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement trans for the MIR Switch terminator #30337
Conversation
rust-highfive
assigned
arielb1
Dec 11, 2015
This comment has been minimized.
This comment has been minimized.
|
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
rust-highfive
assigned
nikomatsakis
and unassigned
arielb1
Dec 11, 2015
nagisa
reviewed
Dec 12, 2015
| Abc::C => 3, | ||
| Abc::D => 4, | ||
| Abc::B(_) => 2, | ||
| Abc::A(_) => 1, |
This comment has been minimized.
This comment has been minimized.
nagisa
reviewed
Dec 12, 2015
|
|
||
| //Use the diverge block for the default case since all enum variants have targets | ||
| //and it shouldn't ever be called | ||
| let diverge_llbb = self.llblock(mir::DIVERGE_BLOCK); |
This comment has been minimized.
This comment has been minimized.
nagisa
reviewed
Dec 12, 2015
| let discr = adt::trans_get_discr(bcx, &*represented_ty, discr_lvalue.llval, None); | ||
|
|
||
| //Use the diverge block for the default case since all enum variants have targets | ||
| //and it shouldn't ever be called |
This comment has been minimized.
This comment has been minimized.
dotdash
reviewed
Dec 12, 2015
| let discr_lvalue = self.trans_lvalue(bcx, discr); | ||
| let discr = adt::trans_get_discr(bcx, &*represented_ty, discr_lvalue.llval, None); | ||
|
|
||
| //Use the diverge block for the default case since all enum variants have targets |
This comment has been minimized.
This comment has been minimized.
dotdash
Dec 12, 2015
Contributor
For exhaustive matches, the default arm of the switch statement should go to a block that only contains an unreachable instruction. LLVM uses that for optimizations.
This comment has been minimized.
This comment has been minimized.
|
@nagisa Fixed nit and added test case for @dotdash I think I fixed this in my last commit. Does that look right to you? |
This comment has been minimized.
This comment has been minimized.
|
@wesleywiser @dotdash regarding
Re EDIT: ah, right, it might be a Thinking about that more, |
This comment has been minimized.
This comment has been minimized.
|
@nagisa AIUI, the fact that the diverge block can contain an |
This comment has been minimized.
This comment has been minimized.
|
@dotdash but all you can really do in that block, really, is having a I’d rather have |
This comment has been minimized.
This comment has been minimized.
|
So, it seems to me that perhaps we should just remove |
This comment has been minimized.
This comment has been minimized.
|
As far as having a special block for unreachable code, that seems fine, but it seems like something specific to trans, and not necessarily something that needs to be made manifest in the MIR. |
nikomatsakis
reviewed
Dec 14, 2015
| unimplemented!() | ||
| mir::Terminator::Switch { ref discr, ref adt_def, ref targets } => { | ||
| let adt_ty = bcx.tcx().lookup_item_type(adt_def.did).ty; | ||
| let represented_ty = adt::represent_type(bcx.ccx(), adt_ty).clone(); |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Dec 14, 2015
| let represented_ty = adt::represent_type(bcx.ccx(), adt_ty).clone(); | ||
|
|
||
| let discr_lvalue = self.trans_lvalue(bcx, discr); | ||
| let discr = adt::trans_get_discr(bcx, &*represented_ty, discr_lvalue.llval, None); |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
reviewed
Dec 14, 2015
| // The else branch of the Switch can't be hit, so branch to an unreachable | ||
| // instruction so LLVM knows that | ||
| let unreachable_blk = bcx.fcx.new_temp_block("enum-variant-unreachable"); | ||
| build::Unreachable(unreachable_blk); |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Dec 14, 2015
Contributor
As @nagisa says, it might be nice to have just one such block (created lazilly), we could store it in the "MIR trans" state.
nikomatsakis
reviewed
Dec 14, 2015
| build::Unreachable(unreachable_blk); | ||
|
|
||
| let switch = build::Switch(bcx, discr, unreachable_blk.llbb, targets.len()); | ||
| for (adt_variant, target) in adt_def.variants.iter().zip(targets) { |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Dec 14, 2015
Contributor
Nit: Please add an assert_eq!(adt_def.variants.len(), targets.len())
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis Fixed nits.
Do you want me to work on that in this PR? |
This comment has been minimized.
This comment has been minimized.
|
You can leave it as it is currently, however, if you can add a FIXME of some sort to that effect. |
This comment has been minimized.
This comment has been minimized.
|
Ok. Should I tidy the branch up too while I'm in there? |
This comment has been minimized.
This comment has been minimized.
|
Sure! |
wesleywiser
force-pushed the
wesleywiser:mir_switch
branch
from
65231f8
to
2b15361
Dec 15, 2015
This comment has been minimized.
This comment has been minimized.
|
I've squashed all my changes and rebased against master. |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ nice! |
This comment has been minimized.
This comment has been minimized.
|
|
wesleywiser commentedDec 11, 2015
Fixes #29574