- Notifications
You must be signed in to change notification settings - Fork13.9k
Implement jump threading MIR opt#107009
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
r?@eholk (rustbot has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Is there any particular reason we need limits on here? Is the runtime potentially infinite, or just O(big) if we have none?
In general, I think it would be neat if we could havesome mechanism to turn off all such limits. For DataflowConstProp I suggested that pass be enabled with limits at opt-level 3, and enabled with no limits at level 4. Of course I'm not aware of any agreement on what opt levels are for so maybe I'm the odd one here.
@bors try@rust-timer queue |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit 36155639f1e6bd248624a49537c61e11be91f233 with merge 64cc3853a551ea0838ed2abeceb8bcc254b99600... |
☀️ Try build successful -checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (64cc3853a551ea0838ed2abeceb8bcc254b99600):comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
Just to check, does this implementation prevent the formation of irreducible control flow? |
@nikic I don't know. I'm not familiar enough with the literature, and I haven't put anything specific to prevent them, so I guess they are not prevented. Do you have pointers on prior work so I can verify/modify the pass properly? |
See theWikipedia entry for the definition of reducibility. I'll review this in a bit though and can make a suggestion then as to how to preserve it |
Uh oh!
There was an error while loading.Please reload this page.
☔ The latest upstream changes (presumably#101692) made this pull request unmergeable. Pleaseresolve the merge conflicts. |
I'm probably not enough of a MIR expert to review this... Re-rolling. @bors r? compiler |
Hmm, I think I see what you are saying. The emphasis in the above quote is on "current", since the recursion doesn't itself change the notion of the "current block" (which I think makes sense, given what the transformation is doing), and so you won't recur more than once. Okay. That seems fine to me; maybe someone later on can look into whether its worth attempting to generalize the code for that case. |
@bors r+ |
I'll think about it. I had an idea how to avoid the current backtracking algorithm, replaced by a single pass on the CFG. But there may be some time before I get around to write it. |
☀️ Test successful -checks-actions |
Finished benchmarking commit (1322f92):comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: missing data |
74: Automated pull from upstream `master` r=tshepang a=github-actions[bot]This PR pulls the following changes from the upstream repository:*rust-lang/rust#117363*rust-lang/rust#116405*rust-lang/rust#117415 *rust-lang/rust#117414 *rust-lang/rust#117411 *rust-lang/rust#117403 *rust-lang/rust#117398 *rust-lang/rust#117396 *rust-lang/rust#117389 *rust-lang/rust#116862*rust-lang/rust#117405 *rust-lang/rust#117395 *rust-lang/rust#117390 *rust-lang/rust#117383 *rust-lang/rust#117376 *rust-lang/rust#117370 *rust-lang/rust#117357 *rust-lang/rust#117356 *rust-lang/rust#117317 *rust-lang/rust#117132 *rust-lang/rust#117068 *rust-lang/rust#112463*rust-lang/rust#117267*rust-lang/rust#116939*rust-lang/rust#117387 *rust-lang/rust#117385 *rust-lang/rust#117382 *rust-lang/rust#117371 *rust-lang/rust#117365 *rust-lang/rust#117350 *rust-lang/rust#117205 *rust-lang/rust#117177 *rust-lang/rust#117147*rust-lang/rust#116485*rust-lang/rust#117328*rust-lang/rust#117332*rust-lang/rust#117089*rust-lang/rust#116733*rust-lang/rust#116889*rust-lang/rust#116270*rust-lang/rust#117354 *rust-lang/rust#117337 *rust-lang/rust#117312 *rust-lang/rust#117082 *rust-lang/rust#117043 *rust-lang/rust#115968*rust-lang/rust#117336 *rust-lang/rust#117325 *rust-lang/rust#117322 *rust-lang/rust#117259 *rust-lang/rust#117170*rust-lang/rust#117335 *rust-lang/rust#117319 *rust-lang/rust#117316 *rust-lang/rust#117311 *rust-lang/rust#117162 *rust-lang/rust#115773*rust-lang/rust#116447*rust-lang/rust#117149*rust-lang/rust#116240*rust-lang/rust#117123*rust-lang/rust#81746*rust-lang/rust#117038*rust-lang/rust#116609*rust-lang/rust#117309 *rust-lang/rust#117277 *rust-lang/rust#117268 *rust-lang/rust#117256 *rust-lang/rust#117025 *rust-lang/rust#116945 *rust-lang/rust#116816 *rust-lang/rust#116739 *rust-lang/rust#116534*rust-lang/rust#117253*rust-lang/rust#117302*rust-lang/rust#117197*rust-lang/rust#116471*rust-lang/rust#117294 *rust-lang/rust#117287 *rust-lang/rust#117281 *rust-lang/rust#117270 *rust-lang/rust#117247 *rust-lang/rust#117246 *rust-lang/rust#117212 *rust-lang/rust#116834*rust-lang/rust#103208*rust-lang/rust#117166*rust-lang/rust#116751*rust-lang/rust#116858*rust-lang/rust#117272 *rust-lang/rust#117266 *rust-lang/rust#117262 *rust-lang/rust#117241 *rust-lang/rust#117240 *rust-lang/rust#116868 *rust-lang/rust#114998*rust-lang/rust#116205*rust-lang/rust#117260*rust-lang/rust#116035*rust-lang/rust#113183*rust-lang/rust#117249 *rust-lang/rust#117243 *rust-lang/rust#117188 *rust-lang/rust#117114 *rust-lang/rust#117106 *rust-lang/rust#117032 *rust-lang/rust#116968*rust-lang/rust#116581*rust-lang/rust#117228 *rust-lang/rust#117221 *rust-lang/rust#117214 *rust-lang/rust#117207 *rust-lang/rust#117202 *rust-lang/rust#117194 *rust-lang/rust#117143 *rust-lang/rust#117095 *rust-lang/rust#116905*rust-lang/rust#117171*rust-lang/rust#113262*rust-lang/rust#112875*rust-lang/rust#116983*rust-lang/rust#117148*rust-lang/rust#117115*rust-lang/rust#116818*rust-lang/rust#115872*rust-lang/rust#117193 *rust-lang/rust#117175 *rust-lang/rust#117009 *rust-lang/rust#117008 *rust-lang/rust#116931 *rust-lang/rust#116553 *rust-lang/rust#116401*rust-lang/rust#117180 *rust-lang/rust#117173 *rust-lang/rust#117163 *rust-lang/rust#117159 *rust-lang/rust#117154 *rust-lang/rust#117152 *rust-lang/rust#117141 *rust-lang/rust#117111*rust-lang/rust#117172 *rust-lang/rust#117168 *rust-lang/rust#117160 *rust-lang/rust#117158 *rust-lang/rust#117150 *rust-lang/rust#117136 *rust-lang/rust#117133 *rust-lang/rust#116801*rust-lang/rust#117165*rust-lang/rust#117113*rust-lang/rust#117102*rust-lang/rust#117076*rust-lang/rust#116236*rust-lang/rust#116993*rust-lang/rust#117139*rust-lang/rust#116482*rust-lang/rust#115796*rust-lang/rust#117135 *rust-lang/rust#117127 *rust-lang/rust#117010 *rust-lang/rust#116943 *rust-lang/rust#116841 *rust-lang/rust#116792 *rust-lang/rust#116714 *rust-lang/rust#116396 *rust-lang/rust#116094*rust-lang/rust#117126 *rust-lang/rust#117105 *rust-lang/rust#117093 *rust-lang/rust#117092 *rust-lang/rust#117091 *rust-lang/rust#117081*rust-lang/rust#116773*rust-lang/rust#117124*rust-lang/rust#116461*rust-lang/rust#116435*rust-lang/rust#116319*rust-lang/rust#116238*rust-lang/rust#116998*rust-lang/rust#116300*rust-lang/rust#117103 *rust-lang/rust#117086 *rust-lang/rust#117074 *rust-lang/rust#117070 *rust-lang/rust#117046 *rust-lang/rust#116859 *rust-lang/rust#107159*rust-lang/rust#116033*rust-lang/rust#107009*rust-lang/rust#117087 *rust-lang/rust#117073 *rust-lang/rust#117064 *rust-lang/rust#117040 *rust-lang/rust#116978 *rust-lang/rust#116960*rust-lang/rust#116837*rust-lang/rust#116835*rust-lang/rust#116849*rust-lang/rust#117071 *rust-lang/rust#117069 *rust-lang/rust#117051 *rust-lang/rust#117049 *rust-lang/rust#117044 *rust-lang/rust#117042 *rust-lang/rust#105666*rust-lang/rust#116606*rust-lang/rust#117066*rust-lang/rust#115324*rust-lang/rust#117062*rust-lang/rust#117000*rust-lang/rust#117007*rust-lang/rust#117018*rust-lang/rust#116256*rust-lang/rust#117041 *rust-lang/rust#117037 *rust-lang/rust#117034 *rust-lang/rust#116989 *rust-lang/rust#116985*rust-lang/rust#116950*rust-lang/rust#116956*rust-lang/rust#116932*rust-lang/rust#117031*rust-lang/rust#117030 *rust-lang/rust#117028 *rust-lang/rust#117026 *rust-lang/rust#116992 *rust-lang/rust#116981 *rust-lang/rust#116955 *rust-lang/rust#116928 *rust-lang/rust#116312*rust-lang/rust#116368*rust-lang/rust#116922*rust-lang/rust#117021*rust-lang/rust#117020 *rust-lang/rust#117019 *rust-lang/rust#116975 *rust-lang/rust#106601*rust-lang/rust#116734*rust-lang/rust#117013 *rust-lang/rust#116995 *rust-lang/rust#116990 *rust-lang/rust#116974 *rust-lang/rust#116964 *rust-lang/rust#116961 *rust-lang/rust#116917 *rust-lang/rust#116911 *rust-lang/rust#114521*rust-lang/rust#117011*rust-lang/rust#116958*rust-lang/rust#116951*rust-lang/rust#116966*rust-lang/rust#116965*rust-lang/rust#116962*rust-lang/rust#116946*rust-lang/rust#116899*rust-lang/rust#116785*rust-lang/rust#116838*rust-lang/rust#116875*rust-lang/rust#116874*rust-lang/rust#115214*rust-lang/rust#116810*rust-lang/rust#116940 *rust-lang/rust#116921 *rust-lang/rust#116906 *rust-lang/rust#116896 *rust-lang/rust#116650*rust-lang/rust#116132*rust-lang/rust#116037*rust-lang/rust#116923 *rust-lang/rust#116912 *rust-lang/rust#116908 *rust-lang/rust#116883 *rust-lang/rust#116829 *rust-lang/rust#116795 *rust-lang/rust#116761 *rust-lang/rust#116663*rust-lang/rust#114534*rust-lang/rust#116402*rust-lang/rust#116493*rust-lang/rust#116046*rust-lang/rust#116887*rust-lang/rust#116885 *rust-lang/rust#116879 *rust-lang/rust#116870 *rust-lang/rust#116865 *rust-lang/rust#116856 *rust-lang/rust#116812*rust-lang/rust#116815*rust-lang/rust#116814*rust-lang/rust#116713*rust-lang/rust#116830Co-authored-by: Matthias Krüger <matthias.krueger@famsik.de>Co-authored-by: antoyo <antoyo@users.noreply.github.com>Co-authored-by: Antoni Boucher <bouanto@zoho.com>Co-authored-by: bors <bors@rust-lang.org>Co-authored-by: Esteban Küber <esteban@kuber.com.ar>Co-authored-by: Kjetil Kjeka <kjetilkjeka@gmail.com>Co-authored-by: clubby789 <jamie@hill-daniel.co.uk>Co-authored-by: okaneco <47607823+okaneco@users.noreply.github.com>Co-authored-by: David Tolnay <dtolnay@gmail.com>Co-authored-by: Nadrieril <nadrieril+git@gmail.com>Co-authored-by: Celina G. Val <celinval@amazon.com>Co-authored-by: Ralf Jung <post@ralfj.de>Co-authored-by: Zalathar <Zalathar@users.noreply.github.com>Co-authored-by: Havard Eidnes <he@NetBSD.org>Co-authored-by: Jacob Pratt <jacob@jhpratt.dev>Co-authored-by: Kjetil Kjeka <kjetil@muybridge.com>
74: Automated pull from upstream `master` r=tshepang a=github-actions[bot]This PR pulls the following changes from the upstream repository:*rust-lang/rust#117363*rust-lang/rust#116405*rust-lang/rust#117415 *rust-lang/rust#117414 *rust-lang/rust#117411 *rust-lang/rust#117403 *rust-lang/rust#117398 *rust-lang/rust#117396 *rust-lang/rust#117389 *rust-lang/rust#116862*rust-lang/rust#117405 *rust-lang/rust#117395 *rust-lang/rust#117390 *rust-lang/rust#117383 *rust-lang/rust#117376 *rust-lang/rust#117370 *rust-lang/rust#117357 *rust-lang/rust#117356 *rust-lang/rust#117317 *rust-lang/rust#117132 *rust-lang/rust#117068 *rust-lang/rust#112463*rust-lang/rust#117267*rust-lang/rust#116939*rust-lang/rust#117387 *rust-lang/rust#117385 *rust-lang/rust#117382 *rust-lang/rust#117371 *rust-lang/rust#117365 *rust-lang/rust#117350 *rust-lang/rust#117205 *rust-lang/rust#117177 *rust-lang/rust#117147*rust-lang/rust#116485*rust-lang/rust#117328*rust-lang/rust#117332*rust-lang/rust#117089*rust-lang/rust#116733*rust-lang/rust#116889*rust-lang/rust#116270*rust-lang/rust#117354 *rust-lang/rust#117337 *rust-lang/rust#117312 *rust-lang/rust#117082 *rust-lang/rust#117043 *rust-lang/rust#115968*rust-lang/rust#117336 *rust-lang/rust#117325 *rust-lang/rust#117322 *rust-lang/rust#117259 *rust-lang/rust#117170*rust-lang/rust#117335 *rust-lang/rust#117319 *rust-lang/rust#117316 *rust-lang/rust#117311 *rust-lang/rust#117162 *rust-lang/rust#115773*rust-lang/rust#116447*rust-lang/rust#117149*rust-lang/rust#116240*rust-lang/rust#117123*rust-lang/rust#81746*rust-lang/rust#117038*rust-lang/rust#116609*rust-lang/rust#117309 *rust-lang/rust#117277 *rust-lang/rust#117268 *rust-lang/rust#117256 *rust-lang/rust#117025 *rust-lang/rust#116945 *rust-lang/rust#116816 *rust-lang/rust#116739 *rust-lang/rust#116534*rust-lang/rust#117253*rust-lang/rust#117302*rust-lang/rust#117197*rust-lang/rust#116471*rust-lang/rust#117294 *rust-lang/rust#117287 *rust-lang/rust#117281 *rust-lang/rust#117270 *rust-lang/rust#117247 *rust-lang/rust#117246 *rust-lang/rust#117212 *rust-lang/rust#116834*rust-lang/rust#103208*rust-lang/rust#117166*rust-lang/rust#116751*rust-lang/rust#116858*rust-lang/rust#117272 *rust-lang/rust#117266 *rust-lang/rust#117262 *rust-lang/rust#117241 *rust-lang/rust#117240 *rust-lang/rust#116868 *rust-lang/rust#114998*rust-lang/rust#116205*rust-lang/rust#117260*rust-lang/rust#116035*rust-lang/rust#113183*rust-lang/rust#117249 *rust-lang/rust#117243 *rust-lang/rust#117188 *rust-lang/rust#117114 *rust-lang/rust#117106 *rust-lang/rust#117032 *rust-lang/rust#116968*rust-lang/rust#116581*rust-lang/rust#117228 *rust-lang/rust#117221 *rust-lang/rust#117214 *rust-lang/rust#117207 *rust-lang/rust#117202 *rust-lang/rust#117194 *rust-lang/rust#117143 *rust-lang/rust#117095 *rust-lang/rust#116905*rust-lang/rust#117171*rust-lang/rust#113262*rust-lang/rust#112875*rust-lang/rust#116983*rust-lang/rust#117148*rust-lang/rust#117115*rust-lang/rust#116818*rust-lang/rust#115872*rust-lang/rust#117193 *rust-lang/rust#117175 *rust-lang/rust#117009 *rust-lang/rust#117008 *rust-lang/rust#116931 *rust-lang/rust#116553 *rust-lang/rust#116401*rust-lang/rust#117180 *rust-lang/rust#117173 *rust-lang/rust#117163 *rust-lang/rust#117159 *rust-lang/rust#117154 *rust-lang/rust#117152 *rust-lang/rust#117141 *rust-lang/rust#117111*rust-lang/rust#117172 *rust-lang/rust#117168 *rust-lang/rust#117160 *rust-lang/rust#117158 *rust-lang/rust#117150 *rust-lang/rust#117136 *rust-lang/rust#117133 *rust-lang/rust#116801*rust-lang/rust#117165*rust-lang/rust#117113*rust-lang/rust#117102*rust-lang/rust#117076*rust-lang/rust#116236*rust-lang/rust#116993*rust-lang/rust#117139*rust-lang/rust#116482*rust-lang/rust#115796*rust-lang/rust#117135 *rust-lang/rust#117127 *rust-lang/rust#117010 *rust-lang/rust#116943 *rust-lang/rust#116841 *rust-lang/rust#116792 *rust-lang/rust#116714 *rust-lang/rust#116396 *rust-lang/rust#116094*rust-lang/rust#117126 *rust-lang/rust#117105 *rust-lang/rust#117093 *rust-lang/rust#117092 *rust-lang/rust#117091 *rust-lang/rust#117081*rust-lang/rust#116773*rust-lang/rust#117124*rust-lang/rust#116461*rust-lang/rust#116435*rust-lang/rust#116319*rust-lang/rust#116238*rust-lang/rust#116998*rust-lang/rust#116300*rust-lang/rust#117103 *rust-lang/rust#117086 *rust-lang/rust#117074 *rust-lang/rust#117070 *rust-lang/rust#117046 *rust-lang/rust#116859 *rust-lang/rust#107159*rust-lang/rust#116033*rust-lang/rust#107009*rust-lang/rust#117087 *rust-lang/rust#117073 *rust-lang/rust#117064 *rust-lang/rust#117040 *rust-lang/rust#116978 *rust-lang/rust#116960*rust-lang/rust#116837*rust-lang/rust#116835*rust-lang/rust#116849*rust-lang/rust#117071 *rust-lang/rust#117069 *rust-lang/rust#117051 *rust-lang/rust#117049 *rust-lang/rust#117044 *rust-lang/rust#117042 *rust-lang/rust#105666*rust-lang/rust#116606*rust-lang/rust#117066*rust-lang/rust#115324*rust-lang/rust#117062*rust-lang/rust#117000*rust-lang/rust#117007*rust-lang/rust#117018*rust-lang/rust#116256*rust-lang/rust#117041 *rust-lang/rust#117037 *rust-lang/rust#117034 *rust-lang/rust#116989 *rust-lang/rust#116985*rust-lang/rust#116950*rust-lang/rust#116956*rust-lang/rust#116932*rust-lang/rust#117031*rust-lang/rust#117030 *rust-lang/rust#117028 *rust-lang/rust#117026 *rust-lang/rust#116992 *rust-lang/rust#116981 *rust-lang/rust#116955 *rust-lang/rust#116928 *rust-lang/rust#116312*rust-lang/rust#116368*rust-lang/rust#116922*rust-lang/rust#117021*rust-lang/rust#117020 *rust-lang/rust#117019 *rust-lang/rust#116975 *rust-lang/rust#106601*rust-lang/rust#116734*rust-lang/rust#117013 *rust-lang/rust#116995 *rust-lang/rust#116990 *rust-lang/rust#116974 *rust-lang/rust#116964 *rust-lang/rust#116961 *rust-lang/rust#116917 *rust-lang/rust#116911 *rust-lang/rust#114521*rust-lang/rust#117011*rust-lang/rust#116958*rust-lang/rust#116951*rust-lang/rust#116966*rust-lang/rust#116965*rust-lang/rust#116962*rust-lang/rust#116946*rust-lang/rust#116899*rust-lang/rust#116785*rust-lang/rust#116838*rust-lang/rust#116875*rust-lang/rust#116874*rust-lang/rust#115214*rust-lang/rust#116810*rust-lang/rust#116940 *rust-lang/rust#116921 *rust-lang/rust#116906 *rust-lang/rust#116896 *rust-lang/rust#116650*rust-lang/rust#116132*rust-lang/rust#116037*rust-lang/rust#116923 *rust-lang/rust#116912 *rust-lang/rust#116908 *rust-lang/rust#116883 *rust-lang/rust#116829 *rust-lang/rust#116795 *rust-lang/rust#116761 *rust-lang/rust#116663*rust-lang/rust#114534*rust-lang/rust#116402*rust-lang/rust#116493*rust-lang/rust#116046*rust-lang/rust#116887*rust-lang/rust#116885 *rust-lang/rust#116879 *rust-lang/rust#116870 *rust-lang/rust#116865 *rust-lang/rust#116856 *rust-lang/rust#116812*rust-lang/rust#116815*rust-lang/rust#116814*rust-lang/rust#116713*rust-lang/rust#116830Co-authored-by: antoyo <antoyo@users.noreply.github.com>Co-authored-by: Antoni Boucher <bouanto@zoho.com>Co-authored-by: bors <bors@rust-lang.org>Co-authored-by: Esteban Küber <esteban@kuber.com.ar>Co-authored-by: Kjetil Kjeka <kjetilkjeka@gmail.com>Co-authored-by: clubby789 <jamie@hill-daniel.co.uk>Co-authored-by: okaneco <47607823+okaneco@users.noreply.github.com>Co-authored-by: David Tolnay <dtolnay@gmail.com>Co-authored-by: Nadrieril <nadrieril+git@gmail.com>Co-authored-by: Celina G. Val <celinval@amazon.com>Co-authored-by: Ralf Jung <post@ralfj.de>Co-authored-by: Zalathar <Zalathar@users.noreply.github.com>Co-authored-by: Havard Eidnes <he@NetBSD.org>Co-authored-by: Jacob Pratt <jacob@jhpratt.dev>Co-authored-by: Kjetil Kjeka <kjetil@muybridge.com>Co-authored-by: Matthias Krüger <matthias.krueger@famsik.de>
Enable ConstGoto and SeparateConstSwitch passes by defaultThese 2 passes implement a limited form of jump-threading.Filing this PR to see if enabling them would be lighter thanrust-lang/rust#107009.
Enable ConstGoto and SeparateConstSwitch passes by defaultThese 2 passes implement a limited form of jump-threading.Filing this PR to see if enabling them would be lighter thanrust-lang/rust#107009.
This pass is an attempt to generalize
ConstGotoandSeparateConstSwitchpasses into a more complete jump threading pass.This pass is rather heavy, as it performs a truncated backwards DFS on MIR starting from each
SwitchIntterminator. This backwards DFS remains very limited, as it only walks throughGototerminators.It is build to support constants and discriminants, and a propagating through a very limited set of operations.
The pass successfully manages to disentangle the
Some(x?)use case and the DFA use case. It still needs a few tests before being ready.