Requiring a pass to run before/after a pass? (Adding PHIs and updating uses)

Is there a simple way to require a pass, e.g., Reg2Mem/Mem2Reg, to run before/after my transformation pass? Or do I do something like:

struct myOpt {
myOpt() {
mBefore = createDemoteRegisterToMemoryPass();
mAfter = createPromoteMemoryToRegisterPass();
}

getAnalysisUsage(AU) {
AU.addRequired(my stuff);
mBefore.getAnalysisUsage(AU);
mAfter.getAnalysisUsage(AU);
}

runOnFunction(aF) {
changed = mBefore(F);
do my stuff;
changed |= mAfter(F);
}
}

I’m trying to transform a CFG where A flows into B and C, and I’m making a copy of A, A_copy, which will also flow into B and C. Right now I’m making a merge point mergeB where both A and A_copy flow into it, and it then flows into B. Same for C.

A
/
B C

A A_copy

/ \ |
mergeB mergeC

B C

For any values %v deffed in A and A_copy, mergeB has the phis %v.phi.B, and I replace the original uses of %v in B with %v.phi.B. However, if both B and C use %v, I need to make sure B gets updated to use %v.phi.B and C gets %v.phi.C (and not %v.phi.B).

I figured I could maybe make the code cleaner by pushing values into alloca slots then doing my transformation and converting back to registers with Reg2Mem then Mem2Reg.

Ed

Is there a simple way to require a pass, e.g., Reg2Mem/Mem2Reg, to run before/after my transformation pass? Or do I do something like:

One simplest way is to handle this is to add these passes around your pass in the pass manager.

pm.add(Reg2Mem)
pm.add(MyPass)
pm.add(Mem2Reg)

How about in the context of opt assuming myOpt is built as part of
llvm and not a separate plugin. It probably wouldn't be ideal to
modify opt.cpp to do something like..

void addPass(PassManager &PM, Pass *P) {
  if (isa<myOpt>(P) {
    addPass(PM, beforePass);
    PM.add(P);
    addPass(PM, afterPass);
  }

And even then, that only fixes opt.

Perhaps Passes can get to the appropriate PassManager by going through
Pass's virtual assignPassManager method?

Ed