"Daniel Stewart" <stewartd at codeaurora.org> writes:> I'm no expert on the PassManager, but I happen to be going through it > fairly carefully right now. You didn't state which passes were Module > Passes and which were Function Passes (or other types).Sorry, I did mean to include that. They are all FunctionPasses.> One thing I have noticed is that addPreserved() doesn't seem to really > do anything. I would have thought it would be used in helping > determine the last users of a pass, but that doesn't appear to be the > case. It seems to mess with a structure called InheritedAnalysis, but > that in turn is never really used for anything.I've also noticed that addPreserved doesn't seem to do anything. Even if I say a pass preserves another pass, the other pass gets run again.> I've noticed that if you have a Module Pass (e.g., GlobalsModRef) that > is used by a function pass, as long as other function passes require > AliasAnalysis, it will stick around, even if one of those passes says > it doesn't preserve AliasAnalysis.Hmm...that might be related. The situation here is that an analysis pass depended on by another analysis pass isn't re-run even though it's not preserved by any pass. It sounds like a similar situation.> As I said, I'm working through the PassManager (LegacyPasssManager.cpp > specifically) now, so my understanding may be a little off. But there > does seem to be some odd behavior of the PassManager that I've > noticed.As far as I know there is no way to force a re-run of a pass. Is that right? -David
You haven't mentioned if your passes are implementers of an interface (like AliasAnalysis). What seems to matter as far as having a pass free'd from memory are the LastUsers. The LastUsers are set by required passes. So if a pass says it requires another pass, the required pass sticks around. The last user is the last pass that required some other particular pass. It appears in your case that F requires A and C. The PassManager will indicate that F is the last user of A. The fact that C doesn't preserve A is seemingly meaningless. Therefore A will be run, followed by C, followed by F. This brings up a question I had about the meaning of "preserve". Some places I read (here on the mailing list + the docs) seem to indicate that preserving is about keeping something around because you may want to use it again. While other places seem to indicate that it is about whether a pass is invalidated. These are very two different things, and, as far as I can tell, the code seems to implement neither of these ideas. To solve your issue, can you use a barrier pass? This might force the passes to re-run when you need them. Daniel -----Original Message----- From: dag at cray.com [mailto:dag at cray.com] Sent: Friday, April 18, 2014 6:03 PM To: Daniel Stewart Cc: dag at cray.com; llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] PassManager Woes "Daniel Stewart" <stewartd at codeaurora.org> writes:> I'm no expert on the PassManager, but I happen to be going through it > fairly carefully right now. You didn't state which passes were Module > Passes and which were Function Passes (or other types).Sorry, I did mean to include that. They are all FunctionPasses.> One thing I have noticed is that addPreserved() doesn't seem to really > do anything. I would have thought it would be used in helping > determine the last users of a pass, but that doesn't appear to be the > case. It seems to mess with a structure called InheritedAnalysis, but > that in turn is never really used for anything.I've also noticed that addPreserved doesn't seem to do anything. Even if I say a pass preserves another pass, the other pass gets run again.> I've noticed that if you have a Module Pass (e.g., GlobalsModRef) that > is used by a function pass, as long as other function passes require > AliasAnalysis, it will stick around, even if one of those passes says > it doesn't preserve AliasAnalysis.Hmm...that might be related. The situation here is that an analysis pass depended on by another analysis pass isn't re-run even though it's not preserved by any pass. It sounds like a similar situation.> As I said, I'm working through the PassManager (LegacyPasssManager.cpp > specifically) now, so my understanding may be a little off. But there > does seem to be some odd behavior of the PassManager that I've > noticed.As far as I know there is no way to force a re-run of a pass. Is that right? -David
"Daniel Stewart" <stewartd at codeaurora.org> writes:> You haven't mentioned if your passes are implementers of an interface > (like AliasAnalysis).No, they're just regular FunctionPasses.> What seems to matter as far as having a pass free'd from memory are > the LastUsers. The LastUsers are set by required passes. So if a pass > says it requires another pass, the required pass sticks around. The > last user is the last pass that required some other particular pass. > It appears in your case that F requires A and C. The PassManager will > indicate that F is the last user of A. The fact that C doesn't > preserve A is seemingly meaningless. Therefore A will be run, > followed by C, followed by F.That's just broken. But I had come to a similar conclusion over the weekend. The obvious question is, if I remove the dependency from F how do I guarantee the information is available when it runs?> This brings up a question I had about the meaning of "preserve". Some > places I read (here on the mailing list + the docs) seem to indicate > that preserving is about keeping something around because you may want > to use it again. While other places seem to indicate that it is about > whether a pass is invalidated. These are very two different things, > and, as far as I can tell, the code seems to implement neither of > these ideas.Spot on.> To solve your issue, can you use a barrier pass? This might force the > passes to re-run when you need them.What's a barrier pass? -David