Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AIEX] Basic LICM pass for control registers #133

Merged
merged 3 commits into from
Aug 6, 2024

Conversation

gbossu
Copy link
Collaborator

@gbossu gbossu commented Jul 22, 2024

This is reviving some older work I made to hoist assignments to CR registers out of loops. This can both hoist to the pre-header, or sink to the exit block. This is needed to clean up our loops so they can later be SW pipelined. QoR shows minor improvements, and one regression: Add2D. What happens is that we now SW-pipeline the inner loop, but spill vector registers. In a future PR, I'll address those spills by teaching the pre-RA scheduler to try even harder to limit register pressure in cases where it is especially high.

E.g.

loop:
  $cr = MOV ...
  USE $cr
  $cr = MOV 0
  JNZ ... loop

into:

  $cr = MOV ...
loop:
  USE $cr
  JNZ ... loop
exit:
  $cr = MOV 0

Limitations:

  • Only supports simple one-bb loops.


using namespace llvm;

#define DEBUG_TYPE "reserved-reg-licm"
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: aie-reserved-reg-licm because this is also the name of the pass.

static MCRegister getSinglePhysRegDef(const MachineInstr &MI) {
if (MI.getNumDefs() == 1 && MI.getNumExplicitDefs() == 1) {
const MachineOperand &MO = MI.getOperand(0);
return MO.isReg() && MO.getReg().isPhysical() ? MO.getReg().asMCReg()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there any possibility that MO is not a register? I think your first If guarantees this condition.

I think it that it can be simpler:

if (MO.getReg().isPhysical()) 
    return MO.getReg().asMCReg();

}

// Traverse instructions to remove defs
for (const MachineInstr &MI : reverse(Header))
Copy link
Collaborator

@andcarminati andcarminati Jul 26, 2024

Choose a reason for hiding this comment

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

I was thinking about one case that one register is defined by a block that dominates the Header. I think this case is not captured here, this register will not be in the live in set.

Can we just trust LoopBody->liveins()? set

Unserstood now: Note we do not need to extend the liveins of the loops BBs with the // newly-hoisted def, because reserved regs are always considered live.

if (MRI->canSimplifyPhysReg(PhysReg)) {
LiveRegs.addReg(PhysReg);
}
}
Copy link
Collaborator

@martien-de-jong martien-de-jong Jul 30, 2024

Choose a reason for hiding this comment

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

I would make this function take a block, not a loop, to make it easier to reuse in multi-block loops. And perhaps split off livereg initialization, which would be different for exiting blocks and internal blocks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I remember in my initial work I extended the pass to support multi-BB loops. Typically outer loops. It was enough to only look in the header, and be conservative if a reserved register was not met there. If I need something more complicated, I'd probably scrap this altogether and extendAIELiveRegs.cpp

@gbossu gbossu force-pushed the gaetan.cr.hoist.sink branch from be68149 to c146a11 Compare July 30, 2024 15:55
Currently this only support sinking into the exit block. Hoisting to the
pre-header will come in a future commit.

Ultimately, this pass could become generic code, as this uses a generic
target hook to determine what is a "safe" reserved register.
@gbossu gbossu force-pushed the gaetan.cr.hoist.sink branch from c146a11 to cbcc052 Compare August 5, 2024 08:54
@gbossu
Copy link
Collaborator Author

gbossu commented Aug 5, 2024

I think I have addressed all the comments now :)

@gbossu gbossu force-pushed the gaetan.cr.hoist.sink branch from cbcc052 to a66f38d Compare August 5, 2024 09:01
martien-de-jong
martien-de-jong previously approved these changes Aug 6, 2024
Copy link
Collaborator

@martien-de-jong martien-de-jong left a comment

Choose a reason for hiding this comment

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

I'm not sure whether you check for dedicated exit to hoist into. For the rest it looks fine.

gbossu added 2 commits August 6, 2024 13:10
The pass will identify phys regs that are defined once in the loop and
are not livein.
Copy link
Collaborator

@andcarminati andcarminati left a comment

Choose a reason for hiding this comment

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

LGTM. Nice work!

@gbossu gbossu enabled auto-merge (rebase) August 6, 2024 13:27
@gbossu gbossu merged commit 895c081 into aie-public Aug 6, 2024
8 checks passed
@gbossu gbossu deleted the gaetan.cr.hoist.sink branch August 6, 2024 14:31
@gbossu gbossu mentioned this pull request Aug 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants