"Should be handled target independently"

EmitInstruction - This callback is invoked when an instruction is emitted , to advance the hazard state .


<s> bool ARCAsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { MF . ensureAlignment ( Align ( 4 ) ) ; return AsmPrinter :: runOnMachineFunction ( MF ) ; } </s>

runOnMachineFunction - Emit the function body .


Targets should implement this to emit instructions .


<s>
StringRef
getPassName
(
)
const
override
{
return
"ARC Assembly Printer"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> bool ARCAsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { MF . ensureAlignment ( Align ( 4 ) ) ; AsmPrinter :: runOnMachineFunction ( MF ) ; } </s>


<s>
bool
ARCBranchFinalize
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
DEBUG
(
dbgs
(
)
<<
"Running ARC Branch Finalize on "
<<
MF
.
getFunction
(
)
->
getName
(
)
<<
"\n"
)
;
std
::
vector
<
MachineInstr
*
>
Branches
;
bool
Changed
=
false
;
unsigned
MaxSize
=
0
;
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
std
::
map
<
MachineBasicBlock
*
,
unsigned
>
BlockToPCMap
;
std
::
vector
<
std
::
pair
<
MachineInstr
*
,
unsigned
>>
BranchToPCList
;
unsigned
PC
=
0
;
for
(
auto
&
MBB
:
MF
)
{
BlockToPCMap
.
insert
(
std
::
make_pair
(
&
MBB
,
PC
)
)
;
for
(
auto
&
MI
:
MBB
)
{
unsigned
Size
=
TII
->
getInstSizeInBytes
(
MI
)
;
if
(
Size
>
8
||
Size
==
0
)
{
DEBUG
(
dbgs
(
)
<<
"Unknown (or size 0) size for: "
<<
MI
<<
"\n"
)
;
}
else
{
MaxSize
+=
Size
;
}
if
(
MI
.
isBranch
(
)
)
{
Branches
.
push_back
(
&
MI
)
;
BranchToPCList
.
emplace_back
(
&
MI
,
PC
)
;
}
PC
+=
Size
;
}
}
for
(
auto
P
:
BranchToPCList
)
{
if
(
isBRccPseudo
(
P
.
first
)
)
isInt
<
9
>
(
MaxSize
)
replaceWithBRcc
(
P
.
first
)
:
replaceWithCmpBcc
(
P
.
first
)
;
}
DEBUG
(
dbgs
(
)
<<
"Estimated function size for "
<<
MF
.
getFunction
(
)
->
getName
(
)
<<
": "
<<
MaxSize
<<
"\n"
)
;
return
Changed
;
}
</s>

ARC
ARC
"Running ARC Branch Finalize on "
"\n"
0
ARC
0
8
0
"Unknown (or size 0) size for: "
"\n"
9
"Estimated function size for "
": "
"\n"


<s>
bool
ARCBranchFinalize
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
DEBUG
(
dbgs
(
)
<<
"Running ARC Branch Finalize on "
<<
MF
.
getName
(
)
<<
"\n"
)
;
std
::
vector
<
MachineInstr
*
>
Branches
;
bool
Changed
=
false
;
unsigned
MaxSize
=
0
;
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
std
::
map
<
MachineBasicBlock
*
,
unsigned
>
BlockToPCMap
;
std
::
vector
<
std
::
pair
<
MachineInstr
*
,
unsigned
>>
BranchToPCList
;
unsigned
PC
=
0
;
for
(
auto
&
MBB
:
MF
)
{
BlockToPCMap
.
insert
(
std
::
make_pair
(
&
MBB
,
PC
)
)
;
for
(
auto
&
MI
:
MBB
)
{
unsigned
Size
=
TII
->
getInstSizeInBytes
(
MI
)
;
if
(
Size
>
8
||
Size
==
0
)
{
DEBUG
(
dbgs
(
)
<<
"Unknown (or size 0) size for: "
<<
MI
<<
"\n"
)
;
}
else
{
MaxSize
+=
Size
;
}
if
(
MI
.
isBranch
(
)
)
{
Branches
.
push_back
(
&
MI
)
;
BranchToPCList
.
emplace_back
(
&
MI
,
PC
)
;
}
PC
+=
Size
;
}
}
for
(
auto
P
:
BranchToPCList
)
{
if
(
isBRccPseudo
(
P
.
first
)
)
isInt
<
9
>
(
MaxSize
)
replaceWithBRcc
(
P
.
first
)
:
replaceWithCmpBcc
(
P
.
first
)
;
}
DEBUG
(
dbgs
(
)
<<
"Estimated function size for "
<<
MF
.
getName
(
)
<<
": "
<<
MaxSize
<<
"\n"
)
;
return
Changed
;
}
</s>


<s>
StringRef
getPassName
(
)
const
override
{
return
"ARC Branch Finalization Pass"
;
}
</s>


<s>
bool
ARCBranchFinalize
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Running ARC Branch Finalize on "
<<
MF
.
getName
(
)
<<
"\n"
)
;
std
::
vector
<
MachineInstr
*
>
Branches
;
bool
Changed
=
false
;
unsigned
MaxSize
=
0
;
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
std
::
map
<
MachineBasicBlock
*
,
unsigned
>
BlockToPCMap
;
std
::
vector
<
std
::
pair
<
MachineInstr
*
,
unsigned
>>
BranchToPCList
;
unsigned
PC
=
0
;
for
(
auto
&
MBB
:
MF
)
{
BlockToPCMap
.
insert
(
std
::
make_pair
(
&
MBB
,
PC
)
)
;
for
(
auto
&
MI
:
MBB
)
{
unsigned
Size
=
TII
->
getInstSizeInBytes
(
MI
)
;
if
(
Size
>
8
||
Size
==
0
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Unknown (or size 0) size for: "
<<
MI
<<
"\n"
)
;
}
else
{
MaxSize
+=
Size
;
}
if
(
MI
.
isBranch
(
)
)
{
Branches
.
push_back
(
&
MI
)
;
BranchToPCList
.
emplace_back
(
&
MI
,
PC
)
;
}
PC
+=
Size
;
}
}
for
(
auto
P
:
BranchToPCList
)
{
if
(
isBRccPseudo
(
P
.
first
)
)
isInt
<
9
>
(
MaxSize
)
replaceWithBRcc
(
P
.
first
)
:
replaceWithCmpBcc
(
P
.
first
)
;
}
LLVM_DEBUG
(
dbgs
(
)
<<
"Estimated function size for "
<<
MF
.
getName
(
)
<<
": "
<<
MaxSize
<<
"\n"
)
;
return
Changed
;
}
</s>


"Successfully decoded 64-bit instruction."

"Not a 64-bit instruction, falling back to 32-bit."

"Successfully decoded 16-bit instruction with limm."

"Not a 16-bit instruction with limm, try without it."

Returns the disassembly of a single instruction .


<s> void ARCExpandPseudos :: expandCTLZ ( MachineFunction & MF , MachineBasicBlock :: iterator MII ) { MachineInstr & MI = * MII ; const MachineOperand & Dest = MI . getOperand ( 0 ) ; const MachineOperand & Src = MI . getOperand ( 1 ) ; Register Ra = MF . getRegInfo ( ) . createVirtualRegister ( & ARC :: GPR32RegClass ) ; Register Rb = MF . getRegInfo ( ) . createVirtualRegister ( & ARC :: GPR32RegClass ) ; BuildMI ( * MI . getParent ( ) , MI , MI . getDebugLoc ( ) , TII -> get ( ARC :: FLS_f_rr ) , Ra ) . add ( Src ) ; BuildMI ( * MI . getParent ( ) , MI , MI . getDebugLoc ( ) , TII -> get ( ARC :: MOV_cc_ru6 ) , Rb ) . addImm ( 32 ) . addImm ( ARCCC :: EQ ) . addReg ( Ra ) ; BuildMI ( * MI . getParent ( ) , MI , MI . getDebugLoc ( ) , TII -> get ( ARC :: RSUB_cc_rru6 ) ) . add ( Dest ) . addImm ( 31 ) . addImm ( ARCCC :: NE ) . addReg ( Rb ) ; MI . eraseFromParent ( ) ; } </s>


<s> void ARCExpandPseudos :: expandCTTZ ( MachineFunction & MF , MachineBasicBlock :: iterator MII ) { MachineInstr & MI = * MII ; const MachineOperand & Dest = MI . getOperand ( 0 ) ; const MachineOperand & Src = MI . getOperand ( 1 ) ; Register R = MF . getRegInfo ( ) . createVirtualRegister ( & ARC :: GPR32RegClass ) ; BuildMI ( * MI . getParent ( ) , MI , MI . getDebugLoc ( ) , TII -> get ( ARC :: FFS_f_rr ) , R ) . add ( Src ) ; BuildMI ( * MI . getParent ( ) , MI , MI . getDebugLoc ( ) , TII -> get ( ARC :: MOV_cc_ru6 ) ) . add ( Dest ) . addImm ( 32 ) . addImm ( ARCCC :: EQ ) . addReg ( R ) ; MI . eraseFromParent ( ) ; } </s>


<s> bool ARCExpandPseudos :: runOnMachineFunction ( MachineFunction & MF ) { const ARCSubtarget * STI = & MF . getSubtarget < ARCSubtarget > ( ) ; TII = STI -> getInstrInfo ( ) ; bool Expanded = false ; for ( auto & MBB : MF ) { MachineBasicBlock :: iterator MBBI = MBB . begin ( ) , E = MBB . end ( ) ; while ( MBBI != E ) { MachineBasicBlock :: iterator NMBBI = std :: next ( MBBI ) ; switch ( MBBI -> getOpcode ( ) ) { case ARC :: ST_FAR : case ARC :: STH_FAR : case ARC :: STB_FAR : expandStore ( MF , MBBI ) ; Expanded = true ; break ; case ARC :: CTLZ : expandCTLZ ( MF , MBBI ) ; Expanded = true ; break ; case ARC :: CTTZ : expandCTTZ ( MF , MBBI ) ; Expanded = true ; break ; default : break ; } MBBI = NMBBI ; } } return Expanded ; } </s>

ARC ARC ARC ARC ARC::ST_FAR ARC::STH_FAR ARC::STB_FAR ARC::CTLZ ARC::CTTZ


<s>
StringRef
getPassName
(
)
const
override
{
return
"ARC Expand Pseudos"
;
}
</s>


<s> bool ARCExpandPseudos :: runOnMachineFunction ( MachineFunction & MF ) { const ARCSubtarget * STI = & MF . getSubtarget < ARCSubtarget > ( ) ; TII = STI -> getInstrInfo ( ) ; bool ExpandedStore = false ; for ( auto & MBB : MF ) { MachineBasicBlock :: iterator MBBI = MBB . begin ( ) , E = MBB . end ( ) ; while ( MBBI != E ) { MachineBasicBlock :: iterator NMBBI = std :: next ( MBBI ) ; switch ( MBBI -> getOpcode ( ) ) { case ARC :: ST_FAR : case ARC :: STH_FAR : case ARC :: STB_FAR : ExpandStore ( MF , MBBI ) ; ExpandedStore = true ; break ; default : break ; } MBBI = NMBBI ; } } return ExpandedStore ; } </s>


<s>
void
ARCFrameLowering
::
determineCalleeSaves
(
MachineFunction
&
MF
,
BitVector
&
SavedRegs
,
RegScavenger
*
RS
)
const
{
DEBUG
(
dbgs
(
)
<<
"Determine Callee Saves: "
<<
MF
.
getName
(
)
<<
"\n"
)
;
TargetFrameLowering
::
determineCalleeSaves
(
MF
,
SavedRegs
,
RS
)
;
SavedRegs
.
set
(
ARC
::
BLINK
)
;
}
</s>

This method determines which of the registers reported by TargetRegisterInfo : :getCalleeSavedRegs ( ) should actually get saved .

ARC
ARC
"Determine Callee Saves: "
"\n"
ARC::BLINK


<s>
MachineBasicBlock
::
iterator
ARCFrameLowering
::
eliminateCallFramePseudoInstr
(
MachineFunction
&
MF
,
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
)
const
{
DEBUG
(
dbgs
(
)
<<
"EmitCallFramePseudo: "
<<
MF
.
getName
(
)
<<
"\n"
)
;
const
ARCInstrInfo
*
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
MachineInstr
&
Old
=
*
I
;
DebugLoc
dl
=
Old
.
getDebugLoc
(
)
;
unsigned
Amt
=
Old
.
getOperand
(
0
)
.
getImm
(
)
;
auto
*
AFI
=
MF
.
getInfo
<
ARCFunctionInfo
>
(
)
;
if
(
!
hasFP
(
MF
)
)
{
if
(
Amt
>
AFI
->
MaxCallStackReq
&&
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
)
AFI
->
MaxCallStackReq
=
Amt
;
}
else
{
if
(
Amt
!=
0
)
{
assert
(
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
||
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
&&
"Unknown Frame Pseudo."
)
;
bool
IsAdd
=
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
;
emitRegUpdate
(
MBB
,
I
,
dl
,
ARC
::
SP
,
Amt
,
IsAdd
,
TII
)
;
}
}
return
MBB
.
erase
(
I
)
;
}
</s>

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy pseudo instructions ( but only if the Target is using them ) .

ARC
ARC
"EmitCallFramePseudo: "
"\n"
ARC
ARC
0
ARC
ARC::ADJCALLSTACKDOWN
0
ARC::ADJCALLSTACKDOWN
ARC::ADJCALLSTACKUP
"Unknown Frame Pseudo."
ARC::ADJCALLSTACKUP
ARC::SP


"Process function before frame finalized: "

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function 's frame layout ( MF.getFrameInfo ( ) ) is finalized .


<s>
bool
ARCFrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
DEBUG
(
dbgs
(
)
<<
"Restore callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>

restoreCalleeSavedRegisters - Issues instruction ( s ) to restore all callee saved registers and returns true if it is n't possible / profitable to do so by issuing a series of load instructions via loadRegToStackSlot ( ) .

ARC
ARC
"Restore callee saved registers: "
"\n"
ARC::R14


<s>
bool
ARCFrameLowering
::
spillCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
DEBUG
(
dbgs
(
)
<<
"Spill callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>

spillCalleeSavedRegisters - Issues instruction ( s ) to spill all callee saved registers and returns true if it is n't possible / profitable to do so by issuing a series of store instructions via storeRegToStackSlot ( ) .

ARC
ARC
"Spill callee saved registers: "
"\n"
ARC::R14


<s>
bool
ARCFrameLowering
::
spillCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
ArrayRef
<
CalleeSavedInfo
>
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Spill callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s>
bool
ARCFrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
MutableArrayRef
<
CalleeSavedInfo
>
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Restore callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s>
bool
ARCFrameLowering
::
assignCalleeSavedSpillSlots
(
MachineFunction
&
MF
,
const
TargetRegisterInfo
*
TRI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
)
const
{
int
CurOffset
=
4
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
if
(
hasFP
(
MF
)
)
{
int
StackObj
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
StackObj
<<
") for FP at "
<<
CurOffset
<<
"\n"
)
;
(
void
)
StackObj
;
CurOffset
-=
4
;
}
if
(
MFI
.
hasCalls
(
)
||
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
)
{
int
StackObj
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
StackObj
<<
") for BLINK at "
<<
CurOffset
<<
"\n"
)
;
(
void
)
StackObj
;
CurOffset
-=
4
;
}
for
(
unsigned
Which
=
Last
;
Which
>
ARC
::
R12
;
Which
)
{
auto
RegI
=
getSavedReg
(
CSI
,
Which
)
;
if
(
RegI
==
CSI
.
end
(
)
||
RegI
->
getFrameIdx
(
)
==
0
)
{
int
FI
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
if
(
RegI
!=
CSI
.
end
(
)
)
RegI
->
setFrameIdx
(
FI
)
;
}
else
MFI
.
setObjectOffset
(
RegI
->
getFrameIdx
(
)
,
CurOffset
)
;
CurOffset
-=
4
;
}
for
(
auto
&
I
:
CSI
)
{
if
(
I
.
getReg
(
)
>
ARC
::
R12
)
continue
;
if
(
I
.
getFrameIdx
(
)
==
0
)
{
I
.
setFrameIdx
(
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
)
;
DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
I
.
getFrameIdx
(
)
<<
") for other register at "
<<
CurOffset
<<
"\n"
)
;
}
else
{
MFI
.
setObjectOffset
(
I
.
getFrameIdx
(
)
,
CurOffset
)
;
DEBUG
(
dbgs
(
)
<<
"Updating fixed object ("
<<
I
.
getFrameIdx
(
)
<<
") for other register at "
<<
CurOffset
<<
"\n"
)
;
}
CurOffset
-=
4
;
}
return
true
;
}
</s>

This function will assign callee saved gprs to volatile vector registers for prologue spills when applicable .


<s>
void
ARCFrameLowering
::
determineCalleeSaves
(
MachineFunction
&
MF
,
BitVector
&
SavedRegs
,
RegScavenger
*
RS
)
const
{
DEBUG
(
dbgs
(
)
<<
"Determine Callee Saves: "
<<
MF
.
getFunction
(
)
->
getName
(
)
<<
"\n"
)
;
TargetFrameLowering
::
determineCalleeSaves
(
MF
,
SavedRegs
,
RS
)
;
SavedRegs
.
set
(
ARC
::
BLINK
)
;
}
</s>


<s>
MachineBasicBlock
::
iterator
ARCFrameLowering
::
eliminateCallFramePseudoInstr
(
MachineFunction
&
MF
,
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
)
const
{
DEBUG
(
dbgs
(
)
<<
"EmitCallFramePseudo: "
<<
MF
.
getFunction
(
)
->
getName
(
)
<<
"\n"
)
;
const
ARCInstrInfo
*
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
MachineInstr
&
Old
=
*
I
;
DebugLoc
dl
=
Old
.
getDebugLoc
(
)
;
unsigned
Amt
=
Old
.
getOperand
(
0
)
.
getImm
(
)
;
auto
*
AFI
=
MF
.
getInfo
<
ARCFunctionInfo
>
(
)
;
if
(
!
hasFP
(
MF
)
)
{
if
(
Amt
>
AFI
->
MaxCallStackReq
&&
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
)
AFI
->
MaxCallStackReq
=
Amt
;
}
else
{
if
(
Amt
!=
0
)
{
assert
(
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
||
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
&&
"Unknown Frame Pseudo."
)
;
bool
IsAdd
=
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
;
emitRegUpdate
(
MBB
,
I
,
dl
,
ARC
::
SP
,
Amt
,
IsAdd
,
TII
)
;
}
}
return
MBB
.
erase
(
I
)
;
}
</s>


<s>
bool
ARCFrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
DEBUG
(
dbgs
(
)
<<
"Restore callee saved registers: "
<<
MBB
.
getParent
(
)
->
getFunction
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s>
bool
ARCFrameLowering
::
spillCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
DEBUG
(
dbgs
(
)
<<
"Spill callee saved registers: "
<<
MBB
.
getParent
(
)
->
getFunction
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s> bool ARCFrameLowering :: hasFP ( const MachineFunction & MF ) const { const TargetRegisterInfo * RegInfo = MF . getSubtarget ( ) . getRegisterInfo ( ) ; bool HasFP = MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || MF . getFrameInfo ( ) . hasVarSizedObjects ( ) || MF . getFrameInfo ( ) . isFrameAddressTaken ( ) || RegInfo -> hasStackRealignment ( MF ) ; return HasFP ; } </s>

hasFP - Return true if the specified function should have a dedicated frame pointer register .


<s>
bool
ARCFrameLowering
::
assignCalleeSavedSpillSlots
(
MachineFunction
&
MF
,
const
TargetRegisterInfo
*
TRI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
)
const
{
int
CurOffset
=
4
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
MachineFrameInfo
&
MFI
=
MF
.
getFrameInfo
(
)
;
if
(
hasFP
(
MF
)
)
{
int
StackObj
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
StackObj
<<
") for FP at "
<<
CurOffset
<<
"\n"
)
;
(
void
)
StackObj
;
CurOffset
-=
4
;
}
if
(
MFI
.
hasCalls
(
)
||
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
)
{
int
StackObj
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
StackObj
<<
") for BLINK at "
<<
CurOffset
<<
"\n"
)
;
(
void
)
StackObj
;
CurOffset
-=
4
;
}
for
(
unsigned
Which
=
Last
;
Which
>
ARC
::
R12
;
Which
)
{
auto
RegI
=
getSavedReg
(
CSI
,
Which
)
;
if
(
RegI
==
CSI
.
end
(
)
||
RegI
->
getFrameIdx
(
)
==
0
)
{
int
FI
=
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
;
if
(
RegI
!=
CSI
.
end
(
)
)
RegI
->
setFrameIdx
(
FI
)
;
}
else
MFI
.
setObjectOffset
(
RegI
->
getFrameIdx
(
)
,
CurOffset
)
;
CurOffset
-=
4
;
}
for
(
auto
&
I
:
CSI
)
{
if
(
I
.
getReg
(
)
>
ARC
::
R12
)
continue
;
if
(
I
.
getFrameIdx
(
)
==
0
)
{
I
.
setFrameIdx
(
MFI
.
CreateFixedSpillStackObject
(
4
,
CurOffset
,
true
)
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Creating fixed object ("
<<
I
.
getFrameIdx
(
)
<<
") for other register at "
<<
CurOffset
<<
"\n"
)
;
}
else
{
MFI
.
setObjectOffset
(
I
.
getFrameIdx
(
)
,
CurOffset
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Updating fixed object ("
<<
I
.
getFrameIdx
(
)
<<
") for other register at "
<<
CurOffset
<<
"\n"
)
;
}
CurOffset
-=
4
;
}
return
true
;
}
</s>


<s>
void
ARCFrameLowering
::
determineCalleeSaves
(
MachineFunction
&
MF
,
BitVector
&
SavedRegs
,
RegScavenger
*
RS
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Determine Callee Saves: "
<<
MF
.
getName
(
)
<<
"\n"
)
;
TargetFrameLowering
::
determineCalleeSaves
(
MF
,
SavedRegs
,
RS
)
;
SavedRegs
.
set
(
ARC
::
BLINK
)
;
}
</s>


<s>
MachineBasicBlock
::
iterator
ARCFrameLowering
::
eliminateCallFramePseudoInstr
(
MachineFunction
&
MF
,
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"EmitCallFramePseudo: "
<<
MF
.
getName
(
)
<<
"\n"
)
;
const
ARCInstrInfo
*
TII
=
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
MachineInstr
&
Old
=
*
I
;
DebugLoc
dl
=
Old
.
getDebugLoc
(
)
;
unsigned
Amt
=
Old
.
getOperand
(
0
)
.
getImm
(
)
;
auto
*
AFI
=
MF
.
getInfo
<
ARCFunctionInfo
>
(
)
;
if
(
!
hasFP
(
MF
)
)
{
if
(
Amt
>
AFI
->
MaxCallStackReq
&&
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
)
AFI
->
MaxCallStackReq
=
Amt
;
}
else
{
if
(
Amt
!=
0
)
{
assert
(
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKDOWN
||
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
&&
"Unknown Frame Pseudo."
)
;
bool
IsAdd
=
(
Old
.
getOpcode
(
)
==
ARC
::
ADJCALLSTACKUP
)
;
emitRegUpdate
(
MBB
,
I
,
dl
,
ARC
::
SP
,
Amt
,
IsAdd
,
TII
)
;
}
}
return
MBB
.
erase
(
I
)
;
}
</s>


<s> bool ARCFrameLowering :: hasFP ( const MachineFunction & MF ) const { const TargetRegisterInfo * RegInfo = MF . getSubtarget ( ) . getRegisterInfo ( ) ; bool HasFP = MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || MF . getFrameInfo ( ) . hasVarSizedObjects ( ) || MF . getFrameInfo ( ) . isFrameAddressTaken ( ) || RegInfo -> needsStackRealignment ( MF ) ; return HasFP ; } </s>


<s>
bool
ARCFrameLowering
::
restoreCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Restore callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s>
bool
ARCFrameLowering
::
spillCalleeSavedRegisters
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
const
std
::
vector
<
CalleeSavedInfo
>
&
CSI
,
const
TargetRegisterInfo
*
TRI
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Spill callee saved registers: "
<<
MBB
.
getParent
(
)
->
getName
(
)
<<
"\n"
)
;
unsigned
Last
=
determineLastCalleeSave
(
CSI
)
;
if
(
UseSaveRestoreFunclet
&&
Last
>
ARC
::
R14
)
{
return
true
;
}
return
false
;
}
</s>


<s> void ARCInstPrinter :: printInst ( const MCInst * MI , uint64_t Address , StringRef Annot , const MCSubtargetInfo & STI , raw_ostream & O ) { printInstruction ( MI , Address , O ) ; printAnnotation ( O , Annot ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


<s> void ARCInstPrinter :: printInst ( const MCInst * MI , raw_ostream & O , StringRef Annot , const MCSubtargetInfo & STI ) { printInstruction ( MI , O ) ; printAnnotation ( O , Annot ) ; } </s>


<s> void ARCInstPrinter :: printRegName ( raw_ostream & OS , unsigned RegNo ) const { OS << StringRef ( getRegisterName ( RegNo ) ) . lower ( ) ; } </s>


<s>
bool
ARCInstrInfo
::
analyzeBranch
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
*
&
TBB
,
MachineBasicBlock
*
&
FBB
,
SmallVectorImpl
<
MachineOperand
>
&
Cond
,
bool
AllowModify
)
const
{
TBB
=
FBB
=
nullptr
;
MachineBasicBlock
::
iterator
I
=
MBB
.
end
(
)
;
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
while
(
isPredicated
(
*
I
)
||
I
->
isTerminator
(
)
||
I
->
isDebugValue
(
)
)
{
bool
CantAnalyze
=
false
;
while
(
I
->
isDebugValue
(
)
||
!
I
->
isTerminator
(
)
)
{
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
}
if
(
isJumpOpcode
(
I
->
getOpcode
(
)
)
)
{
CantAnalyze
=
true
;
}
else
if
(
isUncondBranchOpcode
(
I
->
getOpcode
(
)
)
)
{
TBB
=
I
->
getOperand
(
0
)
.
getMBB
(
)
;
}
else
if
(
isCondBranchOpcode
(
I
->
getOpcode
(
)
)
)
{
if
(
!
Cond
.
empty
(
)
)
return
true
;
assert
(
!
FBB
&&
"FBB should have been null."
)
;
FBB
=
TBB
;
TBB
=
I
->
getOperand
(
0
)
.
getMBB
(
)
;
Cond
.
push_back
(
I
->
getOperand
(
1
)
)
;
Cond
.
push_back
(
I
->
getOperand
(
2
)
)
;
Cond
.
push_back
(
I
->
getOperand
(
3
)
)
;
}
else
if
(
I
->
isReturn
(
)
)
{
CantAnalyze
=
!
isPredicated
(
*
I
)
;
}
else
{
return
true
;
}
if
(
!
isPredicated
(
*
I
)
&&
(
isUncondBranchOpcode
(
I
->
getOpcode
(
)
)
||
isJumpOpcode
(
I
->
getOpcode
(
)
)
||
I
->
isReturn
(
)
)
)
{
Cond
.
clear
(
)
;
FBB
=
nullptr
;
if
(
AllowModify
)
{
MachineBasicBlock
::
iterator
DI
=
std
::
next
(
I
)
;
while
(
DI
!=
MBB
.
end
(
)
)
{
MachineInstr
&
InstToDelete
=
*
DI
;
++
DI
;
InstToDelete
.
eraseFromParent
(
)
;
}
}
}
if
(
CantAnalyze
)
return
true
;
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
}
return
false
;
}
</s>

analyzeBranch - Analyze the branching code at the end of MBB , returning true if it can not be understood ( e.g .


"Couldn't get MachineMemOperand for store to stack."

"Only support 4-byte loads from stack now."

"Only support GPR32 stores to stack now."

Load the specified register of the given register class from the specified stack frame index .


"Only support 4-byte stores to stack now."

Store the specified register of the given register class to the specified stack frame index .


<s>
void
ARCInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
const
DebugLoc
&
dl
,
MCRegister
DestReg
,
MCRegister
SrcReg
,
bool
KillSrc
)
const
{
assert
(
ARC
::
GPR32RegClass
.
contains
(
SrcReg
)
&&
"Only GPR32 src copy supported."
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
DestReg
)
&&
"Only GPR32 dest copy supported."
)
;
BuildMI
(
MBB
,
I
,
dl
,
get
(
ARC
::
MOV_rr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s> bool ARCInstrInfo :: getBaseAndOffsetPosition ( const MachineInstr & MI , unsigned & BasePos , unsigned & OffsetPos ) const { if ( ! MI . mayLoad ( ) && ! MI . mayStore ( ) ) return false ; BasePos = 1 ; OffsetPos = 2 ; if ( isPostIncrement ( MI ) || isPreIncrement ( MI ) ) { BasePos ++ ; OffsetPos ++ ; } if ( ! MI . getOperand ( BasePos ) . isReg ( ) || ! MI . getOperand ( OffsetPos ) . isImm ( ) ) return false ; return true ; } </s>

Return true if the instruction contains a base register and offset .


<s> unsigned ARCInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { if ( MI . isInlineAsm ( ) ) { const MachineFunction * MF = MI . getParent ( ) -> getParent ( ) ; const char * AsmStr = MI . getOperand ( 0 ) . getSymbolName ( ) ; return getInlineAsmLength ( AsmStr , * MF -> getTarget ( ) . getMCAsmInfo ( ) ) ; } return MI . getDesc ( ) . getSize ( ) ; } </s>

Returns the size in bytes of the specified MachineInstr , or ~0U when this function is not implemented by a target .


"insertBranch must not be told to insert a fallthrough"

"ARC branch conditions have two components!"

Insert branch code into the end of the specified MachineBasicBlock .


<s> bool ARCInstrInfo :: isPostIncrement ( const MachineInstr & MI ) const { const MCInstrDesc & MID = MI . getDesc ( ) ; const uint64_t F = MID . TSFlags ; return ( ( F >> TSF_AddrModeOff ) & TSF_AddModeMask ) == PostInc ; } </s>

Return true for post-incremented instructions .


<s>
void
ARCInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
const
DebugLoc
&
DL
,
MCRegister
DestReg
,
MCRegister
SrcReg
,
bool
KillSrc
)
const
{
assert
(
ARC
::
GPR32RegClass
.
contains
(
SrcReg
)
&&
"Only GPR32 src copy supported."
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
DestReg
)
&&
"Only GPR32 dest copy supported."
)
;
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARC
::
MOV_rr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s>
MachineBasicBlock
::
iterator
ARCInstrInfo
::
loadImmediate
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
unsigned
Reg
,
uint64_t
Value
)
const
{
DebugLoc
DL
=
MBB
.
findDebugLoc
(
MI
)
;
if
(
isInt
<
12
>
(
Value
)
)
{
return
BuildMI
(
MBB
,
MI
,
DL
,
get
(
ARC
::
MOV_rs12
)
,
Reg
)
.
addImm
(
Value
)
.
getInstr
(
)
;
}
llvm_unreachable
(
"Need Arc long immediate instructions."
)
;
}
</s>

Emit a series of instructions to load an immediate .


<s>
bool
ARCInstrInfo
::
reverseBranchCondition
(
SmallVectorImpl
<
MachineOperand
>
&
Cond
)
const
{
assert
(
(
Cond
.
size
(
)
==
3
)
&&
"Invalid ARC branch condition!"
)
;
Cond
[
2
]
.
setImm
(
getOppositeBranchCondition
(
(
ARCCC
::
CondCode
)
Cond
[
2
]
.
getImm
(
)
)
)
;
return
false
;
}
</s>

Reverses the branch condition of the specified condition list , returning false on success and true if it can not be reversed .


<s>
bool
ARCInstrInfo
::
analyzeBranch
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
*
&
TBB
,
MachineBasicBlock
*
&
FBB
,
SmallVectorImpl
<
MachineOperand
>
&
Cond
,
bool
AllowModify
)
const
{
TBB
=
FBB
=
nullptr
;
MachineBasicBlock
::
iterator
I
=
MBB
.
end
(
)
;
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
while
(
isPredicated
(
*
I
)
||
I
->
isTerminator
(
)
||
I
->
isDebugValue
(
)
)
{
bool
CantAnalyze
=
false
;
while
(
I
->
isDebugInstr
(
)
||
!
I
->
isTerminator
(
)
)
{
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
}
if
(
isJumpOpcode
(
I
->
getOpcode
(
)
)
)
{
CantAnalyze
=
true
;
}
else
if
(
isUncondBranchOpcode
(
I
->
getOpcode
(
)
)
)
{
TBB
=
I
->
getOperand
(
0
)
.
getMBB
(
)
;
}
else
if
(
isCondBranchOpcode
(
I
->
getOpcode
(
)
)
)
{
if
(
!
Cond
.
empty
(
)
)
return
true
;
assert
(
!
FBB
&&
"FBB should have been null."
)
;
FBB
=
TBB
;
TBB
=
I
->
getOperand
(
0
)
.
getMBB
(
)
;
Cond
.
push_back
(
I
->
getOperand
(
1
)
)
;
Cond
.
push_back
(
I
->
getOperand
(
2
)
)
;
Cond
.
push_back
(
I
->
getOperand
(
3
)
)
;
}
else
if
(
I
->
isReturn
(
)
)
{
CantAnalyze
=
!
isPredicated
(
*
I
)
;
}
else
{
return
true
;
}
if
(
!
isPredicated
(
*
I
)
&&
(
isUncondBranchOpcode
(
I
->
getOpcode
(
)
)
||
isJumpOpcode
(
I
->
getOpcode
(
)
)
||
I
->
isReturn
(
)
)
)
{
Cond
.
clear
(
)
;
FBB
=
nullptr
;
if
(
AllowModify
)
{
MachineBasicBlock
::
iterator
DI
=
std
::
next
(
I
)
;
while
(
DI
!=
MBB
.
end
(
)
)
{
MachineInstr
&
InstToDelete
=
*
DI
;
++
DI
;
InstToDelete
.
eraseFromParent
(
)
;
}
}
}
if
(
CantAnalyze
)
return
true
;
if
(
I
==
MBB
.
begin
(
)
)
return
false
;
I
;
}
return
false
;
}
</s>


<s>
void
ARCInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
const
DebugLoc
&
dl
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
assert
(
ARC
::
GPR32RegClass
.
contains
(
SrcReg
)
&&
"Only GPR32 src copy supported."
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
DestReg
)
&&
"Only GPR32 dest copy supported."
)
;
BuildMI
(
MBB
,
I
,
dl
,
get
(
ARC
::
MOV_rr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s> unsigned ARCInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { if ( MI . getOpcode ( ) == TargetOpcode :: INLINEASM ) { const MachineFunction * MF = MI . getParent ( ) -> getParent ( ) ; const char * AsmStr = MI . getOperand ( 0 ) . getSymbolName ( ) ; return getInlineAsmLength ( AsmStr , * MF -> getTarget ( ) . getMCAsmInfo ( ) ) ; } return MI . getDesc ( ) . getSize ( ) ; } </s>


<s> const ARCRegisterInfo & getRegisterInfo ( ) const { return RI ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


"InsertBranch must not be told to insert a fallthrough"


<s> unsigned ARCInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { int Opcode = MI . getOpcode ( ) ; if ( isLoad ( Opcode ) ) { if ( ( MI . getOperand ( 1 ) . isFI ( ) ) && ( MI . getOperand ( 2 ) . isImm ( ) ) && ( isZeroImm ( MI . getOperand ( 2 ) ) ) ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } } return 0 ; } </s>

isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot , return the virtual or physical register number of the destination along with the FrameIndex of the loaded stack slot .


<s> static bool isStore ( int Opcode ) { return Opcode == ARC :: ST_rs9 || Opcode == ARC :: STH_rs9 || Opcode == ARC :: STB_rs9 ; } </s>

Returns true if this recipe is a store .


<s> unsigned ARCInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { int Opcode = MI . getOpcode ( ) ; if ( isStore ( Opcode ) ) { if ( ( MI . getOperand ( 1 ) . isFI ( ) ) && ( MI . getOperand ( 2 ) . isImm ( ) ) && ( isZeroImm ( MI . getOperand ( 2 ) ) ) ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


<s>
MachineBasicBlock
::
iterator
ARCInstrInfo
::
loadImmediate
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MI
,
unsigned
Reg
,
uint64_t
Value
)
const
{
DebugLoc
dl
=
MBB
.
findDebugLoc
(
MI
)
;
if
(
isInt
<
12
>
(
Value
)
)
{
return
BuildMI
(
MBB
,
MI
,
dl
,
get
(
ARC
::
MOV_rs12
)
,
Reg
)
.
addImm
(
Value
)
.
getInstr
(
)
;
}
llvm_unreachable
(
"Need Arc long immediate instructions."
)
;
}
</s>


"Couldn't get MachineMemOperand for store to stack."

"Only support 4-byte loads from stack now."

"Only support GPR32 stores to stack now."


<s>
unsigned
ARCInstrInfo
::
removeBranch
(
MachineBasicBlock
&
MBB
,
int
*
BytesRemoved
)
const
{
assert
(
!
BytesRemoved
&&
"Code size not handled"
)
;
MachineBasicBlock
::
iterator
I
=
MBB
.
getLastNonDebugInstr
(
)
;
if
(
I
==
MBB
.
end
(
)
)
return
0
;
if
(
!
isUncondBranchOpcode
(
I
->
getOpcode
(
)
)
&&
!
isCondBranchOpcode
(
I
->
getOpcode
(
)
)
)
return
0
;
I
->
eraseFromParent
(
)
;
I
=
MBB
.
end
(
)
;
if
(
I
==
MBB
.
begin
(
)
)
return
1
;
I
;
if
(
!
isCondBranchOpcode
(
I
->
getOpcode
(
)
)
)
return
1
;
I
->
eraseFromParent
(
)
;
return
2
;
}
</s>

Remove the branching code at the end of the specific MBB .


<s>
bool
ARCInstrInfo
::
reverseBranchCondition
(
SmallVectorImpl
<
MachineOperand
>
&
Cond
)
const
{
assert
(
(
Cond
.
size
(
)
==
3
)
&&
"Invalid ARC branch condition!"
)
;
Cond
[
2
]
.
setImm
(
GetOppositeBranchCondition
(
(
ARCCC
::
CondCode
)
Cond
[
2
]
.
getImm
(
)
)
)
;
return
false
;
}
</s>


"Only support 4-byte stores to stack now."


"ARC DAG->DAG Pattern Instruction Selection"

getPassName - Return a nice clean name for a pass .


<s> void ARCDAGToDAGISel :: Select ( SDNode * N ) { switch ( N -> getOpcode ( ) ) { case ISD :: Constant : { uint64_t CVal = cast < ConstantSDNode > ( N ) -> getZExtValue ( ) ; ReplaceNode ( N , CurDAG -> getMachineNode ( isInt < 12 > ( CVal ) ? ARC :: MOV_rs12 : ARC :: MOV_rlimm , SDLoc ( N ) , MVT :: i32 , CurDAG -> getTargetConstant ( CVal , SDLoc ( N ) , MVT :: i32 ) ) ) ; return ; } } SelectCode ( N ) ; } </s>

Main hook for targets to transform nodes into machine nodes .


"Can't return value from vararg function in memory"

This hook must be implemented to lower outgoing return values , described by the Outs array , into the specified DAG .


<s>
SDValue
ARCTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
LowerFRAMEADDR
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSELECT_CC
(
Op
,
DAG
)
;
case
ISD
::
BR_CC
:
return
LowerBR_CC
(
Op
,
DAG
)
;
case
ISD
::
SIGN_EXTEND_INREG
:
return
LowerSIGN_EXTEND_INREG
(
Op
,
DAG
)
;
case
ISD
::
JumpTable
:
return
LowerJumpTable
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
case
ISD
::
READCYCLECOUNTER
:
assert
(
Op
.
getSimpleValueType
(
)
==
MVT
::
i32
)
;
return
Op
;
default
:
llvm_unreachable
(
"unimplemented operand"
)
;
}
}
</s>

LowerOperation - Provide custom lowering hooks for some operations .

ARC
ARC
ISD::GlobalAddress
ISD::FRAMEADDR
ISD::SELECT_CC
ISD::BR_CC
ISD::SIGN_EXTEND_INREG
ISD::JumpTable
ISD::VASTART
ISD::READCYCLECOUNTER
MVT::i32
"unimplemented operand"


<s>
void
ARCTargetLowering
::
ReplaceNodeResults
(
SDNode
*
N
,
SmallVectorImpl
<
SDValue
>
&
Results
,
SelectionDAG
&
DAG
)
const
{
LLVM_DEBUG
(
dbgs
(
)
<<
"[ARC-ISEL] ReplaceNodeResults "
)
;
LLVM_DEBUG
(
N
->
dump
(
&
DAG
)
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"; use_count="
<<
N
->
use_size
(
)
<<
"\n"
)
;
switch
(
N
->
getOpcode
(
)
)
{
case
ISD
::
READCYCLECOUNTER
:
if
(
N
->
getValueType
(
0
)
==
MVT
::
i64
)
{
SDValue
V
=
DAG
.
getNode
(
ISD
::
READCYCLECOUNTER
,
SDLoc
(
N
)
,
DAG
.
getVTList
(
MVT
::
i32
,
MVT
::
Other
)
,
N
->
getOperand
(
0
)
)
;
SDValue
Op
=
DAG
.
getNode
(
ISD
::
ZERO_EXTEND
,
SDLoc
(
N
)
,
MVT
::
i64
,
V
)
;
Results
.
push_back
(
Op
)
;
Results
.
push_back
(
V
.
getValue
(
1
)
)
;
}
break
;
default
:
break
;
}
}
</s>

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built out of custom code .


<s> bool ARCTargetLowering :: CanLowerReturn ( CallingConv :: ID CallConv , MachineFunction & MF , bool IsVarArg , const SmallVectorImpl < ISD :: OutputArg > & Outs , LLVMContext & Context ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , IsVarArg , MF , RVLocs , Context ) ; if ( ! CCInfo . CheckReturn ( Outs , RetCC_ARC ) ) return false ; if ( CCInfo . getNextStackOffset ( ) != 0 && IsVarArg ) return false ; return true ; } </s>

This hook should be implemented to check whether the return values described by the Outs array can fit into the return registers .


<s> const char * ARCTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( Opcode ) { case ARCISD :: BL : return "ARCISD::BL" ; case ARCISD :: CMOV : return "ARCISD::CMOV" ; case ARCISD :: CMP : return "ARCISD::CMP" ; case ARCISD :: BRcc : return "ARCISD::BRcc" ; case ARCISD :: RET : return "ARCISD::RET" ; case ARCISD :: GAWRAPPER : return "ARCISD::GAWRAPPER" ; } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific

ARC ARC ARCISD::BL "ARCISD::BL" ARCISD::CMOV "ARCISD::CMOV" ARCISD::CMP "ARCISD::CMP" ARCISD::BRcc "ARCISD::BRcc" ARCISD::RET "ARCISD::RET" ARCISD::GAWRAPPER "ARCISD::GAWRAPPER"


<s> bool ARCTargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS , Instruction * I ) const { return AM . Scale == 0 ; } </s>

isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target , for a load/store of the specified type .


<s>
SDValue
ARCTargetLowering
::
LowerFormalArguments
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
IsVarArg
,
const
SmallVectorImpl
<
ISD
::
InputArg
>
&
Ins
,
const
SDLoc
&
dl
,
SelectionDAG
&
DAG
,
SmallVectorImpl
<
SDValue
>
&
InVals
)
const
{
switch
(
CallConv
)
{
default
:
llvm_unreachable
(
"Unsupported calling convention"
)
;
case
CallingConv
::
C
:
case
CallingConv
::
Fast
:
return
LowerCallArguments
(
Chain
,
CallConv
,
IsVarArg
,
Ins
,
dl
,
DAG
,
InVals
)
;
}
}
</s>

This hook must be implemented to lower the incoming ( formal ) arguments , described by the Ins array , into the specified DAG .

ARC
ARC
ISD::InputArg
"Unsupported calling convention"


<s>
SDValue
ARCTargetLowering
::
LowerOperation
(
SDValue
Op
,
SelectionDAG
&
DAG
)
const
{
switch
(
Op
.
getOpcode
(
)
)
{
case
ISD
::
GlobalAddress
:
return
LowerGlobalAddress
(
Op
,
DAG
)
;
case
ISD
::
FRAMEADDR
:
return
LowerFRAMEADDR
(
Op
,
DAG
)
;
case
ISD
::
SELECT_CC
:
return
LowerSELECT_CC
(
Op
,
DAG
)
;
case
ISD
::
BR_CC
:
return
LowerBR_CC
(
Op
,
DAG
)
;
case
ISD
::
SIGN_EXTEND_INREG
:
return
LowerSIGN_EXTEND_INREG
(
Op
,
DAG
)
;
case
ISD
::
JumpTable
:
return
LowerJumpTable
(
Op
,
DAG
)
;
case
ISD
::
VASTART
:
return
LowerVASTART
(
Op
,
DAG
)
;
default
:
llvm_unreachable
(
"unimplemented operand"
)
;
}
}
</s>

ARC
ARC
ISD::GlobalAddress
ISD::FRAMEADDR
ISD::SELECT_CC
ISD::BR_CC
ISD::SIGN_EXTEND_INREG
ISD::JumpTable
ISD::VASTART
"unimplemented operand"


<s> bool ARCTargetLowering :: mayBeEmittedAsTailCall ( const CallInst * CI ) const { return false ; } </s>

Return true if the target may be able emit the call instruction as a tail call .


<s> SDValue ARCTargetLowering :: PerformDAGCombine ( SDNode * N , DAGCombinerInfo & DCI ) const { return { } ; } </s>

This method will be invoked for all target nodes and for any target-independent nodes that the target has registered with invoke it for .


<s> bool ARCOptAddrMode :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) || KILL_PASS ( ) ) return false ; if ( DUMP_BEFORE ( ) ) MF . dump ( ) ; if ( VIEW_BEFORE ( ) ) MF . viewCFG ( ) ; AST = & MF . getSubtarget < ARCSubtarget > ( ) ; AII = AST -> getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; bool Changed = false ; for ( auto & MBB : MF ) Changed |= processBasicBlock ( MBB ) ; if ( DUMP_AFTER ( ) ) MF . dump ( ) ; if ( VIEW_AFTER ( ) ) MF . viewCFG ( ) ; return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { AU . setPreservesCFG ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; AU . addRequired < MachineDominatorTree > ( ) ; AU . addPreserved < MachineDominatorTree > ( ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> StringRef getPassName ( ) const override { return OPTADDRMODE_DESC ; } </s>


<s> bool ARCOptAddrMode :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; AST = & MF . getSubtarget < ARCSubtarget > ( ) ; AII = AST -> getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; MDT = & getAnalysis < MachineDominatorTree > ( ) ; bool Changed = false ; for ( auto & MBB : MF ) Changed |= processBasicBlock ( MBB ) ; return Changed ; } </s>


<s>
void
ARCRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected"
)
;
MachineInstr
&
MI
=
*
II
;
MachineOperand
&
FrameOp
=
MI
.
getOperand
(
FIOperandNum
)
;
int
FrameIndex
=
FrameOp
.
getIndex
(
)
;
MachineFunction
&
MF
=
*
MI
.
getParent
(
)
->
getParent
(
)
;
const
ARCInstrInfo
&
TII
=
*
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
const
ARCFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
int
Offset
=
MF
.
getFrameInfo
(
)
.
getObjectOffset
(
FrameIndex
)
;
int
ObjSize
=
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
;
int
StackSize
=
MF
.
getFrameInfo
(
)
.
getStackSize
(
)
;
int
LocalFrameSize
=
MF
.
getFrameInfo
(
)
.
getLocalFrameSize
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"\nFunction         : "
<<
MF
.
getName
(
)
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"<--------->\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
MI
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameIndex         : "
<<
FrameIndex
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ObjSize            : "
<<
ObjSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameOffset        : "
<<
Offset
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"StackSize          : "
<<
StackSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"LocalFrameSize     : "
<<
LocalFrameSize
<<
"\n"
)
;
(
void
)
LocalFrameSize
;
if
(
MI
.
isDebugValue
(
)
)
{
Register
FrameReg
=
getFrameRegister
(
MF
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToRegister
(
FrameReg
,
false
)
;
MI
.
getOperand
(
FIOperandNum
+
1
)
.
ChangeToImmediate
(
Offset
)
;
return
;
}
Offset
+=
MI
.
getOperand
(
FIOperandNum
+
1
)
.
getImm
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Offset             : "
<<
Offset
<<
"\n"
<<
"<--------->\n"
)
;
Register
Reg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
Reg
)
&&
"Unexpected register operand"
)
;
if
(
!
TFI
->
hasFP
(
MF
)
)
{
Offset
=
StackSize
+
Offset
;
if
(
FrameIndex
>=
0
)
assert
(
(
Offset
>=
0
&&
Offset
<
StackSize
)
&&
"SP Offset not in bounds."
)
;
}
else
{
if
(
FrameIndex
>=
0
)
{
assert
(
(
Offset
<
0
&&
Offset
<=
StackSize
)
&&
"FP Offset not in bounds."
)
;
}
}
ReplaceFrameIndex
(
II
,
TII
,
Reg
,
getFrameRegister
(
MF
)
,
Offset
,
StackSize
,
ObjSize
,
RS
,
SPAdj
)
;
}
</s>

This method must be overriden to eliminate abstract frame indices from instructions which may use them .

ARC
ARC
0
"Unexpected"
ARC
ARC
ARC
"\nFunction         : "
"\n"
"<--------->\n"
"\n"
"FrameIndex         : "
"\n"
"ObjSize            : "
"\n"
"FrameOffset        : "
"\n"
"StackSize          : "
"\n"
"LocalFrameSize     : "
"\n"
1
1
"Offset             : "
"\n"
"<--------->\n"
0
ARC::GPR32RegClass
"Unexpected register operand"
0
0
"SP Offset not in bounds."
0
0
"FP Offset not in bounds."


<s> bool ARCRegisterInfo :: needsFrameMoves ( const MachineFunction & MF ) { return MF . needsFrameMoves ( ) ; } </s>


<s>
void
ARCRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected"
)
;
MachineInstr
&
MI
=
*
II
;
MachineOperand
&
FrameOp
=
MI
.
getOperand
(
FIOperandNum
)
;
int
FrameIndex
=
FrameOp
.
getIndex
(
)
;
MachineFunction
&
MF
=
*
MI
.
getParent
(
)
->
getParent
(
)
;
const
ARCInstrInfo
&
TII
=
*
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
const
ARCFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
int
Offset
=
MF
.
getFrameInfo
(
)
.
getObjectOffset
(
FrameIndex
)
;
int
ObjSize
=
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
;
int
StackSize
=
MF
.
getFrameInfo
(
)
.
getStackSize
(
)
;
int
LocalFrameSize
=
MF
.
getFrameInfo
(
)
.
getLocalFrameSize
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"\nFunction         : "
<<
MF
.
getName
(
)
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"<--------->\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
MI
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameIndex         : "
<<
FrameIndex
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ObjSize            : "
<<
ObjSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameOffset        : "
<<
Offset
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"StackSize          : "
<<
StackSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"LocalFrameSize     : "
<<
LocalFrameSize
<<
"\n"
)
;
(
void
)
LocalFrameSize
;
if
(
MI
.
isDebugValue
(
)
)
{
unsigned
FrameReg
=
getFrameRegister
(
MF
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToRegister
(
FrameReg
,
false
)
;
MI
.
getOperand
(
FIOperandNum
+
1
)
.
ChangeToImmediate
(
Offset
)
;
return
;
}
Offset
+=
MI
.
getOperand
(
FIOperandNum
+
1
)
.
getImm
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Offset             : "
<<
Offset
<<
"\n"
<<
"<--------->\n"
)
;
unsigned
Reg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
Reg
)
&&
"Unexpected register operand"
)
;
if
(
!
TFI
->
hasFP
(
MF
)
)
{
Offset
=
StackSize
+
Offset
;
if
(
FrameIndex
>=
0
)
assert
(
(
Offset
>=
0
&&
Offset
<
StackSize
)
&&
"SP Offset not in bounds."
)
;
}
else
{
if
(
FrameIndex
>=
0
)
{
assert
(
(
Offset
<
0
&&
Offset
<=
StackSize
)
&&
"FP Offset not in bounds."
)
;
}
}
ReplaceFrameIndex
(
II
,
TII
,
Reg
,
getFrameRegister
(
MF
)
,
Offset
,
StackSize
,
ObjSize
,
RS
,
SPAdj
)
;
}
</s>


<s>
void
ARCRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected"
)
;
MachineInstr
&
MI
=
*
II
;
MachineOperand
&
FrameOp
=
MI
.
getOperand
(
FIOperandNum
)
;
int
FrameIndex
=
FrameOp
.
getIndex
(
)
;
MachineFunction
&
MF
=
*
MI
.
getParent
(
)
->
getParent
(
)
;
const
ARCInstrInfo
&
TII
=
*
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
const
ARCFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
int
Offset
=
MF
.
getFrameInfo
(
)
.
getObjectOffset
(
FrameIndex
)
;
int
ObjSize
=
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
;
int
StackSize
=
MF
.
getFrameInfo
(
)
.
getStackSize
(
)
;
int
LocalFrameSize
=
MF
.
getFrameInfo
(
)
.
getLocalFrameSize
(
)
;
DEBUG
(
dbgs
(
)
<<
"\nFunction         : "
<<
MF
.
getName
(
)
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"<--------->\n"
)
;
DEBUG
(
dbgs
(
)
<<
MI
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"FrameIndex         : "
<<
FrameIndex
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"ObjSize            : "
<<
ObjSize
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"FrameOffset        : "
<<
Offset
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"StackSize          : "
<<
StackSize
<<
"\n"
)
;
DEBUG
(
dbgs
(
)
<<
"LocalFrameSize     : "
<<
LocalFrameSize
<<
"\n"
)
;
(
void
)
LocalFrameSize
;
if
(
MI
.
isDebugValue
(
)
)
{
unsigned
FrameReg
=
getFrameRegister
(
MF
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToRegister
(
FrameReg
,
false
)
;
MI
.
getOperand
(
FIOperandNum
+
1
)
.
ChangeToImmediate
(
Offset
)
;
return
;
}
Offset
+=
MI
.
getOperand
(
FIOperandNum
+
1
)
.
getImm
(
)
;
DEBUG
(
dbgs
(
)
<<
"Offset             : "
<<
Offset
<<
"\n"
<<
"<--------->\n"
)
;
unsigned
Reg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
Reg
)
&&
"Unexpected register operand"
)
;
if
(
!
TFI
->
hasFP
(
MF
)
)
{
Offset
=
StackSize
+
Offset
;
if
(
FrameIndex
>=
0
)
assert
(
(
Offset
>=
0
&&
Offset
<
StackSize
)
&&
"SP Offset not in bounds."
)
;
}
else
{
if
(
FrameIndex
>=
0
)
{
assert
(
(
Offset
<
0
&&
Offset
<=
StackSize
)
&&
"FP Offset not in bounds."
)
;
}
}
ReplaceFrameIndex
(
II
,
TII
,
Reg
,
getFrameRegister
(
MF
)
,
Offset
,
StackSize
,
ObjSize
,
RS
,
SPAdj
)
;
}
</s>


<s> unsigned ARCRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const ARCFrameLowering * TFI = getFrameLowering ( MF ) ; return TFI -> hasFP ( MF ) ? ARC :: FP : ARC :: SP ; } </s>


<s>
void
ARCRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected"
)
;
MachineInstr
&
MI
=
*
II
;
MachineOperand
&
FrameOp
=
MI
.
getOperand
(
FIOperandNum
)
;
int
FrameIndex
=
FrameOp
.
getIndex
(
)
;
MachineFunction
&
MF
=
*
MI
.
getParent
(
)
->
getParent
(
)
;
const
ARCInstrInfo
&
TII
=
*
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
const
ARCFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
int
Offset
=
MF
.
getFrameInfo
(
)
.
getObjectOffset
(
FrameIndex
)
;
int
ObjSize
=
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
;
int
StackSize
=
MF
.
getFrameInfo
(
)
.
getStackSize
(
)
;
int
LocalFrameSize
=
MF
.
getFrameInfo
(
)
.
getLocalFrameSize
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"\nFunction         : "
<<
MF
.
getName
(
)
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"<--------->\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
MI
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameIndex         : "
<<
FrameIndex
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ObjSize            : "
<<
ObjSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameOffset        : "
<<
Offset
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"StackSize          : "
<<
StackSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"LocalFrameSize     : "
<<
LocalFrameSize
<<
"\n"
)
;
(
void
)
LocalFrameSize
;
if
(
MI
.
isDebugValue
(
)
)
{
Register
FrameReg
=
getFrameRegister
(
MF
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToRegister
(
FrameReg
,
false
)
;
MI
.
getOperand
(
FIOperandNum
+
1
)
.
ChangeToImmediate
(
Offset
)
;
return
;
}
Offset
+=
MI
.
getOperand
(
FIOperandNum
+
1
)
.
getImm
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Offset             : "
<<
Offset
<<
"\n"
<<
"<--------->\n"
)
;
Register
Reg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
Reg
)
&&
"Unexpected register operand"
)
;
if
(
!
TFI
->
hasFP
(
MF
)
)
{
Offset
=
StackSize
+
Offset
;
if
(
FrameIndex
>=
0
)
assert
(
(
Offset
>=
0
&&
Offset
<
StackSize
)
&&
"SP Offset not in bounds."
)
;
}
else
{
if
(
FrameIndex
>=
0
)
{
assert
(
(
Offset
<
0
&&
Offset
<=
StackSize
)
&&
"FP Offset not in bounds."
)
;
}
}
replaceFrameIndex
(
II
,
TII
,
Reg
,
getFrameRegister
(
MF
)
,
Offset
,
StackSize
,
ObjSize
,
RS
,
SPAdj
)
;
}
</s>


<s> bool ARCRegisterInfo :: needsFrameMoves ( const MachineFunction & MF ) { return MF . getMMI ( ) . hasDebugInfo ( ) || MF . getFunction ( ) -> needsUnwindTableEntry ( ) ; } </s>


<s>
void
ARCRegisterInfo
::
eliminateFrameIndex
(
MachineBasicBlock
::
iterator
II
,
int
SPAdj
,
unsigned
FIOperandNum
,
RegScavenger
*
RS
)
const
{
assert
(
SPAdj
==
0
&&
"Unexpected"
)
;
MachineInstr
&
MI
=
*
II
;
MachineOperand
&
FrameOp
=
MI
.
getOperand
(
FIOperandNum
)
;
int
FrameIndex
=
FrameOp
.
getIndex
(
)
;
MachineFunction
&
MF
=
*
MI
.
getParent
(
)
->
getParent
(
)
;
const
ARCInstrInfo
&
TII
=
*
MF
.
getSubtarget
<
ARCSubtarget
>
(
)
.
getInstrInfo
(
)
;
const
ARCFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
int
Offset
=
MF
.
getFrameInfo
(
)
.
getObjectOffset
(
FrameIndex
)
;
int
ObjSize
=
MF
.
getFrameInfo
(
)
.
getObjectSize
(
FrameIndex
)
;
int
StackSize
=
MF
.
getFrameInfo
(
)
.
getStackSize
(
)
;
int
LocalFrameSize
=
MF
.
getFrameInfo
(
)
.
getLocalFrameSize
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"\nFunction         : "
<<
MF
.
getName
(
)
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"<--------->\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
MI
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameIndex         : "
<<
FrameIndex
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ObjSize            : "
<<
ObjSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"FrameOffset        : "
<<
Offset
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"StackSize          : "
<<
StackSize
<<
"\n"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"LocalFrameSize     : "
<<
LocalFrameSize
<<
"\n"
)
;
(
void
)
LocalFrameSize
;
if
(
MI
.
isDebugValue
(
)
)
{
Register
FrameReg
=
getFrameRegister
(
MF
)
;
MI
.
getOperand
(
FIOperandNum
)
.
ChangeToRegister
(
FrameReg
,
false
)
;
MI
.
getOperand
(
FIOperandNum
+
1
)
.
ChangeToImmediate
(
Offset
)
;
return
;
}
Offset
+=
MI
.
getOperand
(
FIOperandNum
+
1
)
.
getImm
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Offset             : "
<<
Offset
<<
"\n"
<<
"<--------->\n"
)
;
unsigned
Reg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
assert
(
ARC
::
GPR32RegClass
.
contains
(
Reg
)
&&
"Unexpected register operand"
)
;
if
(
!
TFI
->
hasFP
(
MF
)
)
{
Offset
=
StackSize
+
Offset
;
if
(
FrameIndex
>=
0
)
assert
(
(
Offset
>=
0
&&
Offset
<
StackSize
)
&&
"SP Offset not in bounds."
)
;
}
else
{
if
(
FrameIndex
>=
0
)
{
assert
(
(
Offset
<
0
&&
Offset
<=
StackSize
)
&&
"FP Offset not in bounds."
)
;
}
}
ReplaceFrameIndex
(
II
,
TII
,
Reg
,
getFrameRegister
(
MF
)
,
Offset
,
StackSize
,
ObjSize
,
RS
,
SPAdj
)
;
}
</s>


<s> const MCPhysReg * ARCRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return CSR_ARC_SaveList ; } </s>


<s> const uint32_t * ARCRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { return CSR_ARC_RegMask ; } </s>

Return a mask of call-preserved registers for the given calling convention on the current function .


<s> Register ARCRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const ARCFrameLowering * TFI = getFrameLowering ( MF ) ; return TFI -> hasFP ( MF ) ? ARC :: FP : ARC :: SP ; } </s>


<s> BitVector ARCRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARC :: ILINK ) ; Reserved . set ( ARC :: SP ) ; Reserved . set ( ARC :: GP ) ; Reserved . set ( ARC :: R25 ) ; Reserved . set ( ARC :: BLINK ) ; Reserved . set ( ARC :: FP ) ; return Reserved ; } </s>

getReservedRegs - Returns a bitset indexed by physical register number indicating if a register is a special register that has particular uses and should be considered unavailable at all times , e.g .

ARC ARC ARC::ILINK ARC::SP ARC::GP ARC::R25 ARC::BLINK ARC::FP


<s> bool ARCRegisterInfo :: needsFrameMoves ( const MachineFunction & MF ) { return MF . getMMI ( ) . hasDebugInfo ( ) || MF . getFunction ( ) . needsUnwindTableEntry ( ) ; } </s>


<s> bool ARCRegisterInfo :: requiresRegisterScavenging ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the target requires ( and can make use of ) the register scavenger .


<s> bool ARCRegisterInfo :: trackLivenessAfterRegAlloc ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the live-ins should be tracked after register allocation .


<s> bool ARCRegisterInfo :: useFPForScavengingIndex ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the target wants to use frame pointer based accesses to spill to the scavenger emergency spill slot .


<s> ARCSubtarget :: ARCSubtarget ( const Triple & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM ) : ARCGenSubtargetInfo ( TT , CPU , CPU , FS ) , InstrInfo ( * this ) , FrameLowering ( * this ) , TLInfo ( TM , * this ) { } </s>

This constructor initializes the data members to match that of the specified triple .


<s> ARCSubtarget :: ARCSubtarget ( const Triple & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM ) : ARCGenSubtargetInfo ( TT , CPU , CPU , FS ) , FrameLowering ( * this ) , TLInfo ( TM , * this ) { } </s>


<s> ARCSubtarget :: ARCSubtarget ( const Triple & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM ) : ARCGenSubtargetInfo ( TT , CPU , FS ) , FrameLowering ( * this ) , TLInfo ( TM , * this ) { } </s>


<s> const ARCInstrInfo * getInstrInfo ( ) const override { return & InstrInfo ; } </s>


<s> const ARCRegisterInfo * getRegisterInfo ( ) const override { return & InstrInfo . getRegisterInfo ( ) ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


ARCTargetMachine ctor - Create an ILP32 architecture model .


<s> void ARCPassConfig :: addPreRegAlloc ( ) { addPass ( createARCExpandPseudosPass ( ) ) ; } </s>

This method may be implemented by targets that want to run passes immediately before register allocation .


<s> TargetTransformInfo ARCTargetMachine :: getTargetTransformInfo ( const Function & F ) const { return TargetTransformInfo ( ARCTTIImpl ( this , F ) ) ; } </s>

Get a TargetTransformInfo implementation for the target .


<s> TargetIRAnalysis ARCTargetMachine :: getTargetIRAnalysis ( ) { return TargetIRAnalysis ( [ this ] ( const Function & F ) { return TargetTransformInfo ( ARCTTIImpl ( this , F ) ) ; } ) ; } </s>

Get a TargetIRAnalysis appropriate for the target .


<s> bool ARCPassConfig :: addInstSelector ( ) { addPass ( createARCISelDag ( getARCTargetMachine ( ) , getOptLevel ( ) ) ) ; return false ; } </s>

addInstSelector - This method should install an instruction selector pass , which converts from LLVM code to machine instructions .


<s> void ARCPassConfig :: addPreEmitPass ( ) { addPass ( createARCBranchFinalizePass ( ) ) ; } </s>

This pass may be implemented by targets that want to run passes immediately before machine code is emitted .


<s> void ARCPassConfig :: addPreRegAlloc ( ) { addPass ( createARCExpandPseudosPass ( ) ) ; addPass ( createARCOptAddrMode ( ) ) ; } </s>


<s> TargetPassConfig * ARCTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new ARCPassConfig ( * this , PM ) ; } </s>

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of CodeGen passes .


<s> TargetLoweringObjectFile * getObjFileLowering ( ) const override { return TLOF . get ( ) ; } </s>

Return information about object file lowering .


<s> const ARCSubtarget * getSubtargetImpl ( const Function & ) const override { return & Subtarget ; } </s>

Virtual method implemented by subclasses that returns a reference to that target 's TargetSubtargetInfo-derived member variable .


<s> TargetTransformInfo ARCTargetMachine :: getTargetTransformInfo ( const Function & F ) { return TargetTransformInfo ( ARCTTIImpl ( this , F ) ) ; } </s>


<s> const ARCTargetLowering * getTLI ( ) const { return TLI ; } </s>

Getter for generic TargetLowering class .