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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s>
StringRef
getPassName
(
)
const
override
{
return
"PULP Hardware Loop Fixup"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s> bool PULPFixupHwLoops :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) { return false ; } bool fixedPreHd = fixupLoopPreheader ( MF ) ; bool fixedLatch = fixupLoopLatch ( MF ) ; bool fixedInstr = fixupLoopInstrs ( MF ) ; for ( MachineBasicBlock & MBB : MF ) { unsigned instrs = 0 ; for ( MachineInstr & MI : MBB ) { instrs ++ ; if ( isHardwareLoop ( MI ) && instrs > 1 ) { MachineBasicBlock * New = splitMBBAt ( & MBB , MI ) ; if ( New == & MBB ) { continue ; } New -> setAlignment ( Align ( 4 ) ) ; break ; } } } return fixedPreHd || fixedLatch || fixedInstr ; } </s>

runOnMachineFunction - Emit the function body .


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


<s>
StringRef
getPassName
(
)
const
override
{
return
"PULP Hardware Loops"
;
}
</s>


<s>
unsigned
getReg
(
)
const
{
assert
(
isReg
(
)
&&
"Wrong CountValue accessor"
)
;
return
Contents
.
R
.
Reg
;
}
</s>

Returns the register associated with this edge .


<s>
unsigned
getSubReg
(
)
const
{
assert
(
isReg
(
)
&&
"Wrong CountValue accessor"
)
;
return
Contents
.
R
.
Sub
;
}
</s>

Returns the physical register number of sub-register `` Index '' for physical register RegNo .


<s> bool PULPHardwareLoops :: isDead ( const MachineInstr * MI , SmallVectorImpl < MachineInstr * > & DeadPhis ) const { for ( unsigned i = 0 , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || ! MO . isDef ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( MRI -> use_nodbg_empty ( Reg ) ) continue ; using use_nodbg_iterator = MachineRegisterInfo :: use_nodbg_iterator ; use_nodbg_iterator I = MRI -> use_nodbg_begin ( Reg ) ; use_nodbg_iterator End = MRI -> use_nodbg_end ( ) ; if ( std :: next ( I ) != End || ! I -> getParent ( ) -> isPHI ( ) ) return false ; MachineInstr * OnePhi = I -> getParent ( ) ; for ( unsigned j = 0 , f = OnePhi -> getNumOperands ( ) ; j != f ; ++ j ) { const MachineOperand & OPO = OnePhi -> getOperand ( j ) ; if ( ! OPO . isReg ( ) || ! OPO . isDef ( ) ) continue ; unsigned OPReg = OPO . getReg ( ) ; use_nodbg_iterator nextJ ; for ( use_nodbg_iterator J = MRI -> use_nodbg_begin ( OPReg ) ; J != End ; J = nextJ ) { nextJ = std :: next ( J ) ; MachineOperand & Use = * J ; MachineInstr * UseMI = Use . getParent ( ) ; if ( MI != UseMI ) return false ; } } DeadPhis . push_back ( OnePhi ) ; } return true ; } </s>

isDead - Returns true if this is a dead def kill slot .


<s> bool isImm ( ) const { return Kind == CV_Immediate ; } </s>


<s> bool isReg ( ) const { return Kind == CV_Register ; } </s>


<s> static bool isSigned ( Kind Cmp ) { return ( Cmp & ( L | G ) && ! ( Cmp & U ) ) ; } </s>

Returns true if all source operands of the recurrence are SExtInsts .


<s> void print ( raw_ostream & OS , const TargetRegisterInfo * TRI = nullptr ) const { if ( isReg ( ) ) { OS << printReg ( Contents . R . Reg , TRI , Contents . R . Sub ) ; } if ( isImm ( ) ) { OS << Contents . ImmVal ; } } </s>

print - Print a debug representation of the operand to the given stream .


<s>
void
RISCVAsmBackend
::
applyFixup
(
const
MCAssembler
&
Asm
,
const
MCFixup
&
Fixup
,
const
MCValue
&
Target
,
MutableArrayRef
<
char
>
Data
,
uint64_t
Value
,
bool
IsResolved
,
const
MCSubtargetInfo
*
STI
)
const
{
MCFixupKind
Kind
=
Fixup
.
getKind
(
)
;
if
(
Kind
>=
FirstLiteralRelocationKind
)
return
;
MCContext
&
Ctx
=
Asm
.
getContext
(
)
;
MCFixupKindInfo
Info
=
getFixupKindInfo
(
Kind
)
;
if
(
!
Value
)
return
;
Value
=
adjustFixupValue
(
Fixup
,
Value
,
Ctx
)
;
Value
<<=
Info
.
TargetOffset
;
unsigned
Offset
=
Fixup
.
getOffset
(
)
;
unsigned
NumBytes
=
alignTo
(
Info
.
TargetSize
+
Info
.
TargetOffset
,
8
)
/
8
;
assert
(
Offset
+
NumBytes
<=
Data
.
size
(
)
&&
"Invalid fixup offset!"
)
;
for
(
unsigned
i
=
0
;
i
!=
NumBytes
;
++
i
)
{
Data
[
Offset
+
i
]
|=
uint8_t
(
(
Value
>>
(
i
*
8
)
)
&
0xff
)
;
}
}
</s>

Apply the Value for given Fixup into the provided data fragment , at the offset specified by the fixup and following the fixup kind as appropriate .


Simple predicate for targets where ! Resolved implies requiring relaxation .


<s> bool RISCVAsmBackend :: fixupNeedsRelaxationAdvanced ( const MCFixup & Fixup , bool Resolved , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout , const bool WasForced ) const { if ( ! Resolved && ! WasForced ) return true ; int64_t Offset = int64_t ( Value ) ; switch ( Fixup . getTargetKind ( ) ) { default : return false ; case RISCV :: fixup_riscv_rvc_branch : return Offset > 254 || Offset < - 256 ; case RISCV :: fixup_riscv_rvc_jump : return Offset > 2046 || Offset < - 2048 ; } } </s>

Target specific predicate for whether a given fixup requires the associated instruction to be relaxed .


<s> Optional < MCFixupKind > RISCVAsmBackend :: getFixupKind ( StringRef Name ) const { if ( STI . getTargetTriple ( ) . isOSBinFormatELF ( ) ) { unsigned Type ; Type = llvm :: StringSwitch < unsigned > ( Name ) . Default ( - 1u ) ; if ( Type != - 1u ) return static_cast < MCFixupKind > ( FirstLiteralRelocationKind + Type ) ; } return None ; } </s>

getFixupKind - Get the fixup kind of this expression .


"Not all fixup kinds added to Infos array"


<s> unsigned getNumFixupKinds ( ) const override { return RISCV :: NumTargetFixupKinds ; } </s>

Get the number of target specific fixup kinds .


<s> bool RISCVAsmBackend :: mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const { return getRelaxedOpcode ( Inst . getOpcode ( ) ) != Inst . getOpcode ( ) ; } </s>

Check whether the given instruction may need relaxation .


<s>
void
RISCVAsmBackend
::
relaxInstruction
(
MCInst
&
Inst
,
const
MCSubtargetInfo
&
STI
)
const
{
MCInst
Res
;
switch
(
Inst
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Opcode not expected!"
)
;
case
RISCV
::
C_BEQZ
:
Res
.
setOpcode
(
RISCV
::
BEQ
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
RISCV
::
X0
)
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
1
)
)
;
break
;
case
RISCV
::
C_BNEZ
:
Res
.
setOpcode
(
RISCV
::
BNE
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
0
)
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
RISCV
::
X0
)
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
1
)
)
;
break
;
case
RISCV
::
C_J
:
Res
.
setOpcode
(
RISCV
::
JAL
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
RISCV
::
X0
)
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
0
)
)
;
break
;
case
RISCV
::
C_JAL
:
Res
.
setOpcode
(
RISCV
::
JAL
)
;
Res
.
addOperand
(
MCOperand
::
createReg
(
RISCV
::
X1
)
)
;
Res
.
addOperand
(
Inst
.
getOperand
(
0
)
)
;
break
;
}
Inst
=
std
::
move
(
Res
)
;
}
</s>

Relax the instruction in the given fragment to the next wider instruction .


<s> bool RISCVAsmBackend :: shouldForceRelocation ( const MCAssembler & Asm , const MCFixup & Fixup , const MCValue & Target ) { if ( Fixup . getKind ( ) >= FirstLiteralRelocationKind ) return true ; switch ( Fixup . getTargetKind ( ) ) { default : break ; case FK_Data_1 : case FK_Data_2 : case FK_Data_4 : case FK_Data_8 : if ( Target . isAbsolute ( ) ) return false ; break ; case RISCV :: fixup_riscv_got_hi20 : case RISCV :: fixup_riscv_tls_got_hi20 : case RISCV :: fixup_riscv_tls_gd_hi20 : return true ; case RISCV :: fixup_pulpv2_loop_setup : case RISCV :: fixup_pulpv2_loop_setupi : return false ; } return STI . getFeatureBits ( ) [ RISCV :: FeatureRelax ] || ForceRelocs ; } </s>

Hook to check if a relocation is needed for some target specific reason .


<s> bool RISCVAsmBackend :: shouldInsertExtraNopBytesForCodeAlign ( const MCAlignFragment & AF , unsigned & Size ) { if ( ! STI . getFeatureBits ( ) [ RISCV :: FeatureRelax ] ) return false ; bool HasStdExtC = STI . getFeatureBits ( ) [ RISCV :: FeatureStdExtC ] ; unsigned MinNopLen = HasStdExtC ? 2 : 4 ; if ( AF . getAlignment ( ) <= MinNopLen ) { return false ; } else { Size = AF . getAlignment ( ) - MinNopLen ; return true ; } } </s>

Hook to check if extra nop bytes must be inserted for alignment directive .


<s> bool RISCVAsmBackend :: shouldInsertFixupForCodeAlign ( MCAssembler & Asm , const MCAsmLayout & Layout , MCAlignFragment & AF ) { if ( ! STI . getFeatureBits ( ) [ RISCV :: FeatureRelax ] ) return false ; unsigned Count ; if ( ! shouldInsertExtraNopBytesForCodeAlign ( AF , Count ) || ( Count == 0 ) ) return false ; MCContext & Ctx = Asm . getContext ( ) ; const MCExpr * Dummy = MCConstantExpr :: create ( 0 , Ctx ) ; MCFixup Fixup = MCFixup :: create ( 0 , Dummy , MCFixupKind ( RISCV :: fixup_riscv_align ) , SMLoc ( ) ) ; uint64_t FixedValue = 0 ; MCValue NopBytes = MCValue :: get ( Count ) ; Asm . getWriter ( ) . recordRelocation ( Asm , Layout , & AF , Fixup , NopBytes , FixedValue ) ; return true ; } </s>

Hook which indicates if the target requires a fixup to be generated when handling an align directive in an executable section .


<s> bool RISCVAsmBackend :: writeNopData ( raw_ostream & OS , uint64_t Count ) const { bool HasStdExtC = STI . getFeatureBits ( ) [ RISCV :: FeatureStdExtC ] ; unsigned MinNopLen = HasStdExtC ? 2 : 4 ; if ( ( Count % MinNopLen ) != 0 ) return false ; for ( ; Count >= 4 ; Count -= 4 ) OS . write ( "\x13\0\0\0" , 4 ) ; if ( Count && HasStdExtC ) OS . write ( "\x01\0" , 2 ) ; return true ; } </s>

Write an ( optimal ) nop sequence of Count bytes to the given output .


<s>
void
addExpr
(
MCInst
&
Inst
,
const
MCExpr
*
Expr
)
const
{
assert
(
Expr
&&
"Expr shouldn't be null!"
)
;
int64_t
Imm
=
0
;
RISCVMCExpr
::
VariantKind
VK
=
RISCVMCExpr
::
VK_RISCV_None
;
bool
IsConstant
=
evaluateConstantImm
(
Expr
,
Imm
,
VK
)
;
if
(
IsConstant
)
Inst
.
addOperand
(
MCOperand
::
createImm
(
Imm
)
)
;
else
Inst
.
addOperand
(
MCOperand
::
createExpr
(
Expr
)
)
;
}
</s>

RI5CY
"Expr shouldn't be null!"
0
RISCV
RISCV
RISCV


<s> SMLoc getEndLoc ( ) const override { return EndLoc ; } </s>

getEndLoc - Get the location of the last token of this operand .


<s> SMLoc getLoc ( ) const { return getParser ( ) . getTok ( ) . getLoc ( ) ; } </s>

Get the source location of the point where the field was defined .


<s>
unsigned
getReg
(
)
const
override
{
assert
(
Kind
==
KindTy
::
Register
&&
"Invalid type access!"
)
;
return
Reg
.
RegNum
.
id
(
)
;
}
</s>

Returns the register associated with this edge .


<s> SMLoc getStartLoc ( ) const override { return StartLoc ; } </s>

getStartLoc - Get the location of the first token of this operand .


<s> bool isImm ( ) const override { return Kind == KindTy :: Immediate ; } </s>


<s> bool isMem ( ) const override { return false ; } </s>


<s> bool isReg ( ) const override { return Kind == KindTy :: Register ; } </s>


<s> bool isToken ( ) const override { return Kind == KindTy :: Token ; } </s>


<s> bool RISCVAsmParser :: ParseDirective ( AsmToken DirectiveID ) { StringRef IDVal = DirectiveID . getString ( ) ; if ( IDVal == ".option" ) return parseDirectiveOption ( ) ; else if ( IDVal == ".attribute" ) return parseDirectiveAttribute ( ) ; return true ; } </s>

ParseDirective - Parse a target specific assembler directive This method is deprecated , use 'parseDirective ' instead .


<s>
bool
RISCVAsmParser
::
ParseInstruction
(
ParseInstructionInfo
&
Info
,
StringRef
Name
,
SMLoc
NameLoc
,
OperandVector
&
Operands
)
{
if
(
getSTI
(
)
.
getFeatureBits
(
)
[
RISCV
::
FeatureRelax
]
)
{
auto
*
Assembler
=
getTargetStreamer
(
)
.
getStreamer
(
)
.
getAssemblerPtr
(
)
;
if
(
Assembler
!=
nullptr
)
{
RISCVAsmBackend
&
MAB
=
static_cast
<
RISCVAsmBackend
&
>
(
Assembler
->
getBackend
(
)
)
;
MAB
.
setForceRelocs
(
)
;
}
}
Operands
.
push_back
(
RISCVOperand
::
createToken
(
Name
,
NameLoc
,
isRV64
(
)
)
)
;
if
(
getLexer
(
)
.
is
(
AsmToken
::
EndOfStatement
)
)
return
false
;
if
(
parseOperand
(
Operands
,
Name
)
)
return
true
;
unsigned
OperandIdx
=
1
;
while
(
getLexer
(
)
.
is
(
AsmToken
::
Comma
)
)
{
getLexer
(
)
.
Lex
(
)
;
if
(
parseOperand
(
Operands
,
Name
)
)
return
true
;
++
OperandIdx
;
}
if
(
getLexer
(
)
.
isNot
(
AsmToken
::
EndOfStatement
)
)
{
SMLoc
Loc
=
getLexer
(
)
.
getLoc
(
)
;
getParser
(
)
.
eatToEndOfStatement
(
)
;
return
Error
(
Loc
,
"unexpected token"
)
;
}
getParser
(
)
.
Lex
(
)
;
return
false
;
}
</s>

ParseInstruction - Parse one assembly instruction .

RI5CY
RISCV
RISCV::FeatureRelax
RISCV
RISCV
RISCV
1
"unexpected token"


<s>
void
print
(
raw_ostream
&
OS
)
const
override
{
auto
RegName
=
[
]
(
unsigned
Reg
)
{
if
(
Reg
)
return
RISCVInstPrinter
::
getRegisterName
(
Reg
)
;
else
return
"noreg"
;
}
;
switch
(
Kind
)
{
case
KindTy
::
Immediate
:
OS
<<
*
getImm
(
)
;
break
;
case
KindTy
::
Register
:
OS
<<
"<register "
<<
RegName
(
getReg
(
)
)
<<
">"
;
break
;
case
KindTy
::
Token
:
OS
<<
"'"
<<
getToken
(
)
<<
"'"
;
break
;
case
KindTy
::
SystemRegister
:
OS
<<
"<sysreg: "
<<
getSysReg
(
)
<<
'>'
;
break
;
case
KindTy
::
VType
:
OS
<<
"<vtype: "
;
RISCVVType
::
printVType
(
getVType
(
)
,
OS
)
;
OS
<<
'>'
;
break
;
}
}
</s>

print - Print a debug representation of the operand to the given stream .

RI5CY
RISCV
"noreg"
"<register "
">"
"'"
"'"
"<sysreg: "
"<vtype: "
RISCV


<s> OperandMatchResultTy RISCVAsmParser :: tryParseRegister ( unsigned & RegNo , SMLoc & StartLoc , SMLoc & EndLoc ) { const AsmToken & Tok = getParser ( ) . getTok ( ) ; StartLoc = Tok . getLoc ( ) ; EndLoc = Tok . getEndLoc ( ) ; RegNo = 0 ; StringRef Name = getLexer ( ) . getTok ( ) . getIdentifier ( ) ; if ( matchRegisterNameHelper ( isRV32E ( ) , ( MCRegister & ) RegNo , Name ) ) return MatchOperand_NoMatch ; getParser ( ) . Lex ( ) ; return MatchOperand_Success ; } </s>

tryParseRegister - parse one register if possible


<s> unsigned RISCVAsmParser :: validateTargetOperandClass ( MCParsedAsmOperand & AsmOp , unsigned Kind ) { RISCVOperand & Op = static_cast < RISCVOperand & > ( AsmOp ) ; if ( ! Op . isReg ( ) ) return Match_InvalidOperand ; MCRegister Reg = Op . getReg ( ) ; bool IsRegFPR64 = RISCVMCRegisterClasses [ RISCV :: FPR64RegClassID ] . contains ( Reg ) ; bool IsRegFPR64C = RISCVMCRegisterClasses [ RISCV :: FPR64CRegClassID ] . contains ( Reg ) ; if ( ( IsRegFPR64 && Kind == MCK_FPR32 ) || ( IsRegFPR64C && Kind == MCK_FPR32C ) ) { Op . Reg . RegNum = convertFPR64ToFPR32 ( Reg ) ; return Match_Success ; } if ( IsRegFPR64 && Kind == MCK_FPR16 ) { Op . Reg . RegNum = convertFPR64ToFPR16 ( Reg ) ; return Match_Success ; } return Match_InvalidOperand ; } </s>

Allow a target to add special case operand matching for things that tblgen doesn't/ca n't handle effectively .


<s> void RISCVAsmPrinter :: emitEndOfAsmFile ( Module & M ) { RISCVTargetStreamer & RTS = static_cast < RISCVTargetStreamer & > ( * OutStreamer -> getTargetStreamer ( ) ) ; if ( TM . getTargetTriple ( ) . isOSBinFormatELF ( ) ) RTS . finishAttributeSection ( ) ; } </s>

This virtual method can be overridden by targets that want to emit something at the end of their file .


<s> void RISCVAsmPrinter :: emitInstruction ( const MachineInstr * MI ) { if ( emitPseudoExpansionLowering ( * OutStreamer , MI ) ) return ; MCInst TmpInst ; LowerRISCVMachineInstrToMCInst ( MI , TmpInst , * this ) ; EmitToStreamer ( * OutStreamer , TmpInst ) ; } </s>

Targets should implement this to emit instructions .


<s> void RISCVAsmPrinter :: emitStartOfAsmFile ( Module & M ) { if ( TM . getTargetTriple ( ) . isOSBinFormatELF ( ) ) emitAttributes ( ) ; } </s>

This virtual method can be overridden by targets that want to emit something at the start of their file .


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

getPassName - Return a nice clean name for a pass .


<s> bool lowerOperand ( const MachineOperand & MO , MCOperand & MCOp ) const { return LowerRISCVMachineOperandToMCOperand ( MO , MCOp , * this ) ; } </s>

Wrapper for MCInstLowering.lowerOperand ( ) for the tblgen'erated pseudo lowering .


<s> bool RISCVAsmPrinter :: PrintAsmMemoryOperand ( const MachineInstr * MI , unsigned OpNo , const char * ExtraCode , raw_ostream & OS ) { if ( ! ExtraCode ) { const MachineOperand & MO = MI -> getOperand ( OpNo ) ; if ( ! MO . isReg ( ) ) return true ; OS << "0(" << RISCVInstPrinter :: getRegisterName ( MO . getReg ( ) ) << ")" ; return false ; } return AsmPrinter :: PrintAsmMemoryOperand ( MI , OpNo , ExtraCode , OS ) ; } </s>

Print the specified operand of MI , an INLINEASM instruction , using the specified assembler variant as an address .


<s> bool RISCVAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , const char * ExtraCode , raw_ostream & OS ) { if ( ! AsmPrinter :: PrintAsmOperand ( MI , OpNo , ExtraCode , OS ) ) return false ; const MachineOperand & MO = MI -> getOperand ( OpNo ) ; if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; switch ( ExtraCode [ 0 ] ) { default : return true ; case 'z' : if ( MO . isImm ( ) && MO . getImm ( ) == 0 ) { OS << RISCVInstPrinter :: getRegisterName ( RISCV :: X0 ) ; return false ; } break ; case 'i' : if ( ! MO . isReg ( ) ) OS << 'i' ; return false ; } } switch ( MO . getType ( ) ) { case MachineOperand :: MO_Immediate : OS << MO . getImm ( ) ; return false ; case MachineOperand :: MO_Register : OS << RISCVInstPrinter :: getRegisterName ( MO . getReg ( ) ) ; return false ; case MachineOperand :: MO_GlobalAddress : PrintSymbolOperand ( MO , OS ) ; return false ; case MachineOperand :: MO_BlockAddress : { MCSymbol * Sym = GetBlockAddressSymbol ( MO . getBlockAddress ( ) ) ; Sym -> print ( OS , MAI ) ; return false ; } default : break ; } return true ; } </s>

PrintAsmOperand - Print out an operand for an inline asm expression .


<s> bool RISCVAsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { MCSubtargetInfo & NewSTI = OutStreamer -> getContext ( ) . getSubtargetCopy ( * TM . getMCSubtargetInfo ( ) ) ; NewSTI . setFeatureBits ( MF . getSubtarget ( ) . getFeatureBits ( ) ) ; STI = & NewSTI ; SetupMachineFunction ( MF ) ; emitFunctionBody ( ) ; return false ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool RISCVCallLowering :: lowerCall ( MachineIRBuilder & MIRBuilder , CallLoweringInfo & Info ) const { return false ; } </s>

This hook must be implemented to lower the given call instruction , including argument and return value marshalling .


<s> bool RISCVCallLowering :: lowerFormalArguments ( MachineIRBuilder & MIRBuilder , const Function & F , ArrayRef < ArrayRef < Register >> VRegs , FunctionLoweringInfo & FLI ) const { if ( F . arg_empty ( ) ) return true ; return false ; } </s>

This hook must be implemented to lower the incoming ( formal ) arguments , described by VRegs , for GlobalISel .


<s> bool RISCVCallLowering :: lowerReturn ( MachineIRBuilder & MIRBuilder , const Value * Val , ArrayRef < Register > VRegs , FunctionLoweringInfo & FLI ) const { MachineInstrBuilder Ret = MIRBuilder . buildInstrNoInsert ( RISCV :: PseudoRET ) ; if ( Val != nullptr ) { return false ; } MIRBuilder . insertInstr ( Ret ) ; return true ; } </s>

This hook behaves as the extended lowerReturn function , but for targets that do not support swifterror value promotion .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


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


<s> bool RISCVCleanupVSETVLI :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; const RISCVSubtarget & ST = MF . getSubtarget < RISCVSubtarget > ( ) ; if ( ! ST . hasStdExtV ( ) ) return false ; bool Changed = false ; for ( MachineBasicBlock & MBB : MF ) Changed |= runOnMachineBasicBlock ( MBB ) ; return Changed ; } </s>


"Trying RISCV32Only_16 table (16-bit Instruction):\n"

"Trying RVBC32 table (BitManip 16-bit Instruction):\n"

"Trying RISCV_C table (16-bit Instruction):\n"

Returns the disassembly of a single instruction .


<s> MCELFStreamer & RISCVTargetELFStreamer :: getStreamer ( ) { return static_cast < MCELFStreamer & > ( Streamer ) ; } </s>

Return the output streamer for the assembler .


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


<s> bool RISCVExpandAtomicPseudo :: runOnMachineFunction ( MachineFunction & MF ) { TII = static_cast < const RISCVInstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; bool Modified = false ; for ( auto & MBB : MF ) Modified |= expandMBB ( MBB ) ; return Modified ; } </s>


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


<s> bool RISCVExpandPseudo :: runOnMachineFunction ( MachineFunction & MF ) { TII = static_cast < const RISCVInstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; bool Modified = false ; for ( auto & MBB : MF ) Modified |= expandMBB ( MBB ) ; return Modified ; } </s>


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


<s> bool RISCVExpandSDMA :: runOnMachineFunction ( MachineFunction & MF ) { TII = static_cast < const RISCVInstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; bool Modified = false ; for ( auto & MBB : MF ) Modified |= expandMBB ( MBB ) ; return Modified ; } </s>


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


<s> bool RISCVExpandSSR :: runOnMachineFunction ( MachineFunction & MF ) { TII = static_cast < const RISCVInstrInfo * > ( MF . getSubtarget ( ) . getInstrInfo ( ) ) ; this -> MF = & MF ; this -> RVFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; Enabled = false ; bool Modified = false ; for ( auto & MBB : MF ) Modified |= expandMBB ( MBB ) ; RISCVExpandSSR :: RegisterMergingPreferences RMP = gatherRegisterMergingPreferences ( ) ; if ( RMP . Enable && RVFI -> getUsedSSR ( ) ) for ( auto & MBB : MF ) mergePushPop ( MBB ) ; if ( Modified ) { for ( auto & MBB : MF ) { for ( unsigned ssr_no = 0 ; ssr_no < NUM_SSR ; ++ ssr_no ) MBB . addLiveIn ( getSSRFtReg ( ssr_no ) ) ; MBB . sortUniqueLiveIns ( ) ; } } return Modified ; } </s>


<s> bool RISCVFrameLowering :: canUseAsEpilogue ( const MachineBasicBlock & MBB ) const { const MachineFunction * MF = MBB . getParent ( ) ; MachineBasicBlock * TmpMBB = const_cast < MachineBasicBlock * > ( & MBB ) ; const auto * RVFI = MF -> getInfo < RISCVMachineFunctionInfo > ( ) ; if ( ! RVFI -> useSaveRestoreLibCalls ( * MF ) ) return true ; if ( MBB . succ_size ( ) > 1 ) return false ; MachineBasicBlock * SuccMBB = MBB . succ_empty ( ) ? TmpMBB -> getFallThrough ( ) : * MBB . succ_begin ( ) ; if ( ! SuccMBB ) return true ; return SuccMBB -> isReturnBlock ( ) && SuccMBB -> size ( ) == 1 ; } </s>

Check whether or not the given MBB can be used as a epilogue for the target .


<s> bool RISCVFrameLowering :: canUseAsPrologue ( const MachineBasicBlock & MBB ) const { MachineBasicBlock * TmpMBB = const_cast < MachineBasicBlock * > ( & MBB ) ; const MachineFunction * MF = MBB . getParent ( ) ; const auto * RVFI = MF -> getInfo < RISCVMachineFunctionInfo > ( ) ; if ( ! RVFI -> useSaveRestoreLibCalls ( * MF ) ) return true ; RegScavenger RS ; RS . enterBasicBlock ( * TmpMBB ) ; return ! RS . isRegUsed ( RISCV :: X5 ) ; } </s>

Check whether or not the given MBB can be used as a prologue for the target .


<s> void RISCVFrameLowering :: determineCalleeSaves ( MachineFunction & MF , BitVector & SavedRegs , RegScavenger * RS ) const { TargetFrameLowering :: determineCalleeSaves ( MF , SavedRegs , RS ) ; if ( hasFP ( MF ) ) { SavedRegs . set ( RISCV :: X1 ) ; SavedRegs . set ( RISCV :: X8 ) ; } if ( hasBP ( MF ) ) SavedRegs . set ( RISCVABI :: getBPReg ( ) ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; if ( MF . getFunction ( ) . hasFnAttribute ( "interrupt" ) && MFI . hasCalls ( ) ) { static const MCPhysReg CSRegs [ ] = { RISCV :: X1 , RISCV :: X5 , RISCV :: X6 , RISCV :: X7 , RISCV :: X10 , RISCV :: X11 , RISCV :: X12 , RISCV :: X13 , RISCV :: X14 , RISCV :: X15 , RISCV :: X16 , RISCV :: X17 , RISCV :: X28 , RISCV :: X29 , RISCV :: X30 , RISCV :: X31 , 0 } ; for ( unsigned i = 0 ; CSRegs [ i ] ; ++ i ) SavedRegs . set ( CSRegs [ i ] ) ; if ( MF . getSubtarget < RISCVSubtarget > ( ) . hasStdExtF ( ) ) { const MCPhysReg * Regs = MF . getRegInfo ( ) . getCalleeSavedRegs ( ) ; for ( unsigned i = 0 ; Regs [ i ] ; ++ i ) if ( RISCV :: FPR16RegClass . contains ( Regs [ i ] ) || RISCV :: FPR32RegClass . contains ( Regs [ i ] ) || RISCV :: FPR64RegClass . contains ( Regs [ i ] ) ) SavedRegs . set ( Regs [ i ] ) ; } } } </s>

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


<s> void RISCVFrameLowering :: determineFrameLayout ( MachineFunction & MF ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; uint64_t FrameSize = MFI . getStackSize ( ) ; Align StackAlign = getStackAlign ( ) ; uint64_t MaxCallSize = alignTo ( MFI . getMaxCallFrameSize ( ) , StackAlign ) ; MFI . setMaxCallFrameSize ( MaxCallSize ) ; FrameSize = alignTo ( FrameSize , StackAlign ) ; MFI . setStackSize ( FrameSize ) ; } </s>

Determine the frame layout but do not update the machine function .


<s> MachineBasicBlock :: iterator RISCVFrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI ) const { Register SPReg = RISCV :: X2 ; DebugLoc DL = MI -> getDebugLoc ( ) ; if ( ! hasReservedCallFrame ( MF ) ) { int64_t Amount = MI -> getOperand ( 0 ) . getImm ( ) ; if ( Amount != 0 ) { Amount = alignSPAdjust ( Amount ) ; if ( MI -> getOpcode ( ) == RISCV :: ADJCALLSTACKDOWN ) Amount = - Amount ; adjustReg ( MBB , MI , DL , SPReg , SPReg , Amount , MachineInstr :: NoFlags ) ; } } return MBB . erase ( MI ) ; } </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 ) .


"frame pointer should not have been eliminated"

"SecondSPAdjustAmount should be greater than zero"


<s> StackOffset RISCVFrameLowering :: getFrameIndexReference ( const MachineFunction & MF , int FI , Register & FrameReg ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const TargetRegisterInfo * RI = MF . getSubtarget ( ) . getRegisterInfo ( ) ; const auto * RVFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; const auto & CSI = getNonLibcallCSI ( MFI . getCalleeSavedInfo ( ) ) ; int MinCSFI = 0 ; int MaxCSFI = - 1 ; int Offset = MFI . getObjectOffset ( FI ) - getOffsetOfLocalArea ( ) + MFI . getOffsetAdjustment ( ) ; uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount ( MF ) ; if ( CSI . size ( ) ) { MinCSFI = CSI [ 0 ] . getFrameIdx ( ) ; MaxCSFI = CSI [ CSI . size ( ) - 1 ] . getFrameIdx ( ) ; } if ( FI >= MinCSFI && FI <= MaxCSFI ) { FrameReg = RISCV :: X2 ; if ( FirstSPAdjustAmount ) Offset += FirstSPAdjustAmount ; else Offset += MFI . getStackSize ( ) ; } else if ( RI -> needsStackRealignment ( MF ) && ! MFI . isFixedObjectIndex ( FI ) ) { if ( hasBP ( MF ) ) FrameReg = RISCVABI :: getBPReg ( ) ; else FrameReg = RISCV :: X2 ; Offset += MFI . getStackSize ( ) ; if ( FI < 0 ) Offset += RVFI -> getLibCallStackSize ( ) ; } else { FrameReg = RI -> getFrameRegister ( MF ) ; if ( hasFP ( MF ) ) { Offset += RVFI -> getVarArgsSaveSize ( ) ; if ( FI >= 0 ) Offset -= RVFI -> getLibCallStackSize ( ) ; } else { Offset += MFI . getStackSize ( ) ; if ( FI < 0 ) Offset += RVFI -> getLibCallStackSize ( ) ; } } return StackOffset :: getFixed ( Offset ) ; } </s>

getFrameIndexReference - This method should return the base register and offset used to reference a frame index location .


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

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


<s> bool RISCVFrameLowering :: hasReservedCallFrame ( const MachineFunction & MF ) const { return ! MF . getFrameInfo ( ) . hasVarSizedObjects ( ) ; } </s>

hasReservedCallFrame - Under normal circumstances , when a frame pointer is not required , we reserve argument space for call sites in the function immediately on entry to the current function .


<s> void RISCVFrameLowering :: processFunctionBeforeFrameFinalized ( MachineFunction & MF , RegScavenger * RS ) const { const TargetRegisterInfo * RegInfo = MF . getSubtarget ( ) . getRegisterInfo ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const TargetRegisterClass * RC = & RISCV :: GPRRegClass ; if ( ! isInt < 11 > ( MFI . estimateStackSize ( MF ) ) ) { int RegScavFI = MFI . CreateStackObject ( RegInfo -> getSpillSize ( * RC ) , RegInfo -> getSpillAlign ( * RC ) , false ) ; RS -> addScavengingFrameIndex ( RegScavFI ) ; } } </s>

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


"loadRegFromStackSlot didn't insert any code!"

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 ( ) .


<s> bool RISCVFrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , ArrayRef < CalleeSavedInfo > CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return true ; MachineFunction * MF = MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF -> getSubtarget ( ) . getInstrInfo ( ) ; DebugLoc DL ; if ( MI != MBB . end ( ) && ! MI -> isDebugInstr ( ) ) DL = MI -> getDebugLoc ( ) ; const char * SpillLibCall = getSpillLibCallName ( * MF , CSI ) ; if ( SpillLibCall ) { BuildMI ( MBB , MI , DL , TII . get ( RISCV :: PseudoCALLReg ) , RISCV :: X5 ) . addExternalSymbol ( SpillLibCall , RISCVII :: MO_CALL ) . setMIFlag ( MachineInstr :: FrameSetup ) ; for ( auto & CS : CSI ) MBB . addLiveIn ( CS . getReg ( ) ) ; } const auto & NonLibcallCSI = getNonLibcallCSI ( CSI ) ; for ( auto & CS : NonLibcallCSI ) { Register Reg = CS . getReg ( ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; TII . storeRegToStackSlot ( MBB , MI , Reg , true , CS . getFrameIdx ( ) , RC , TRI ) ; } return true ; } </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 ( ) .


<s> bool RISCVInstPrinter :: applyTargetSpecificCLOption ( StringRef Opt ) { if ( Opt == "no-aliases" ) { NoAliases = true ; return true ; } if ( Opt == "numeric" ) { ArchRegNames = true ; return true ; } return false ; } </s>

Customize the printer according to a command line option .


<s> void RISCVInstPrinter :: printInst ( const MCInst * MI , uint64_t Address , StringRef Annot , const MCSubtargetInfo & STI , raw_ostream & O ) { bool Res = false ; const MCInst * NewMI = MI ; MCInst UncompressedMI ; if ( ! NoAliases ) Res = uncompressInst ( UncompressedMI , * MI , MRI , STI ) ; if ( Res ) NewMI = const_cast < MCInst * > ( & UncompressedMI ) ; if ( NoAliases || ! printAliasInstr ( NewMI , Address , STI , O ) ) printInstruction ( NewMI , Address , STI , O ) ; printAnnotation ( O , Annot ) ; } </s>

Print the specified MCInst to the specified raw_ostream .


<s> void RISCVInstPrinter :: printRegName ( raw_ostream & O , unsigned RegNo ) const { O << getRegisterName ( RegNo ) ; } </s>


<s> bool RISCVInstrInfo :: analyzeBranch ( MachineBasicBlock & MBB , MachineBasicBlock * & TBB , MachineBasicBlock * & FBB , SmallVectorImpl < MachineOperand > & Cond , bool AllowModify ) const { TBB = FBB = nullptr ; Cond . clear ( ) ; MachineBasicBlock :: iterator I = MBB . getLastNonDebugInstr ( ) ; if ( I == MBB . end ( ) || ! isUnpredicatedTerminator ( * I ) ) return false ; MachineBasicBlock :: iterator FirstUncondOrIndirectBr = MBB . end ( ) ; int NumTerminators = 0 ; for ( auto J = I . getReverse ( ) ; J != MBB . rend ( ) && isUnpredicatedTerminator ( * J ) ; J ++ ) { NumTerminators ++ ; if ( J -> getDesc ( ) . isUnconditionalBranch ( ) || J -> getDesc ( ) . isIndirectBranch ( ) ) { FirstUncondOrIndirectBr = J . getReverse ( ) ; } } if ( AllowModify && FirstUncondOrIndirectBr != MBB . end ( ) ) { while ( std :: next ( FirstUncondOrIndirectBr ) != MBB . end ( ) ) { std :: next ( FirstUncondOrIndirectBr ) -> eraseFromParent ( ) ; NumTerminators -- ; } I = FirstUncondOrIndirectBr ; } if ( I -> getDesc ( ) . isIndirectBranch ( ) ) return true ; if ( NumTerminators > 2 ) return true ; if ( NumTerminators == 1 && I -> getDesc ( ) . isUnconditionalBranch ( ) ) { TBB = getBranchDestBlock ( * I ) ; return false ; } if ( NumTerminators == 1 && I -> getDesc ( ) . isConditionalBranch ( ) ) { parseCondBranch ( * I , TBB , Cond ) ; return false ; } if ( NumTerminators == 2 && std :: prev ( I ) -> getDesc ( ) . isConditionalBranch ( ) && I -> getDesc ( ) . isUnconditionalBranch ( ) ) { parseCondBranch ( * std :: prev ( I ) , TBB , Cond ) ; FBB = getBranchDestBlock ( * I ) ; return false ; } return true ; } </s>

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


<s>
bool
RISCVInstrInfo
::
areMemAccessesTriviallyDisjoint
(
const
MachineInstr
&
MIa
,
const
MachineInstr
&
MIb
)
const
{
assert
(
MIa
.
mayLoadOrStore
(
)
&&
"MIa must be a load or store."
)
;
assert
(
MIb
.
mayLoadOrStore
(
)
&&
"MIb must be a load or store."
)
;
if
(
MIa
.
hasUnmodeledSideEffects
(
)
||
MIb
.
hasUnmodeledSideEffects
(
)
||
MIa
.
hasOrderedMemoryRef
(
)
||
MIb
.
hasOrderedMemoryRef
(
)
)
return
false
;
const
TargetRegisterInfo
*
TRI
=
STI
.
getRegisterInfo
(
)
;
const
MachineOperand
*
BaseOpA
=
nullptr
,
*
BaseOpB
=
nullptr
;
int64_t
OffsetA
=
0
,
OffsetB
=
0
;
unsigned
int
WidthA
=
0
,
WidthB
=
0
;
if
(
getMemOperandWithOffsetWidth
(
MIa
,
BaseOpA
,
OffsetA
,
WidthA
,
TRI
)
&&
getMemOperandWithOffsetWidth
(
MIb
,
BaseOpB
,
OffsetB
,
WidthB
,
TRI
)
)
{
if
(
BaseOpA
->
isIdenticalTo
(
*
BaseOpB
)
)
{
int
LowOffset
=
std
::
min
(
OffsetA
,
OffsetB
)
;
int
HighOffset
=
std
::
max
(
OffsetA
,
OffsetB
)
;
int
LowWidth
=
(
LowOffset
==
OffsetA
)
WidthA
:
WidthB
;
if
(
LowOffset
+
LowWidth
<=
HighOffset
)
return
true
;
}
}
return
false
;
}
</s>

Sometimes , it is possible for the target to tell , even without aliasing information , that two MIs access different memory addresses .


<s> void RISCVInstrInfo :: buildOutlinedFrame ( MachineBasicBlock & MBB , MachineFunction & MF , const outliner :: OutlinedFunction & OF ) const { bool Changed = true ; while ( Changed ) { Changed = false ; auto I = MBB . begin ( ) ; auto E = MBB . end ( ) ; for ( ; I != E ; ++ I ) { if ( I -> isCFIInstruction ( ) ) { I -> removeFromParent ( ) ; Changed = true ; break ; } } } MBB . addLiveIn ( RISCV :: X5 ) ; MBB . insert ( MBB . end ( ) , BuildMI ( MF , DebugLoc ( ) , get ( RISCV :: JALR ) ) . addReg ( RISCV :: X0 , RegState :: Define ) . addReg ( RISCV :: X5 ) . addImm ( 0 ) ) ; } </s>

Insert a custom frame for outlined functions .


<s>
void
RISCVInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
MBBI
,
const
DebugLoc
&
DL
,
MCRegister
DstReg
,
MCRegister
SrcReg
,
bool
KillSrc
)
const
{
if
(
RISCV
::
GPRRegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
RISCV
::
ADDI
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
.
addImm
(
0
)
;
return
;
}
unsigned
Opc
;
bool
IsScalableVector
=
false
;
if
(
RISCV
::
FPR16RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
RISCV
::
FSGNJ_H
;
else
if
(
RISCV
::
FPR32RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
RISCV
::
FSGNJ_S
;
else
if
(
RISCV
::
FPR64RegClass
.
contains
(
DstReg
,
SrcReg
)
)
Opc
=
RISCV
::
FSGNJ_D
;
else
if
(
RISCV
::
VRRegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
Opc
=
RISCV
::
PseudoVMV1R_V
;
IsScalableVector
=
true
;
}
else
if
(
RISCV
::
VRM2RegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
Opc
=
RISCV
::
PseudoVMV2R_V
;
IsScalableVector
=
true
;
}
else
if
(
RISCV
::
VRM4RegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
Opc
=
RISCV
::
PseudoVMV4R_V
;
IsScalableVector
=
true
;
}
else
if
(
RISCV
::
VRM8RegClass
.
contains
(
DstReg
,
SrcReg
)
)
{
Opc
=
RISCV
::
PseudoVMV8R_V
;
IsScalableVector
=
true
;
}
else
llvm_unreachable
(
"Impossible reg-to-reg copy"
)
;
if
(
IsScalableVector
)
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
else
BuildMI
(
MBB
,
MBBI
,
DL
,
get
(
Opc
)
,
DstReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
}
</s>


<s> std :: pair < unsigned , unsigned > RISCVInstrInfo :: decomposeMachineOperandsTargetFlags ( unsigned TF ) const { const unsigned Mask = RISCVII :: MO_DIRECT_FLAG_MASK ; return std :: make_pair ( TF & Mask , TF & ~ Mask ) ; } </s>

Decompose the machine operand 's target flags into two values - the direct target flag value and any of bit flags that are applied .


<s> unsigned RISCVInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { unsigned Opcode = MI . getOpcode ( ) ; switch ( Opcode ) { default : { if ( MI . getParent ( ) && MI . getParent ( ) -> getParent ( ) ) { const auto MF = MI . getMF ( ) ; const auto & TM = static_cast < const RISCVTargetMachine & > ( MF -> getTarget ( ) ) ; const MCRegisterInfo & MRI = * TM . getMCRegisterInfo ( ) ; const MCSubtargetInfo & STI = * TM . getMCSubtargetInfo ( ) ; const RISCVSubtarget & ST = MF -> getSubtarget < RISCVSubtarget > ( ) ; if ( isCompressibleInst ( MI , & ST , MRI , STI ) ) return 2 ; } return get ( Opcode ) . getSize ( ) ; } case TargetOpcode :: EH_LABEL : case TargetOpcode :: IMPLICIT_DEF : case TargetOpcode :: KILL : case TargetOpcode :: DBG_VALUE : return 0 ; case RISCV :: PseudoCALLReg : case RISCV :: PseudoCALL : case RISCV :: PseudoJump : case RISCV :: PseudoTAIL : case RISCV :: PseudoLLA : case RISCV :: PseudoLA : case RISCV :: PseudoLA_TLS_IE : case RISCV :: PseudoLA_TLS_GD : return 8 ; case RISCV :: PseudoAtomicLoadNand32 : case RISCV :: PseudoAtomicLoadNand64 : return 20 ; case RISCV :: PseudoMaskedAtomicSwap32 : case RISCV :: PseudoMaskedAtomicLoadAdd32 : case RISCV :: PseudoMaskedAtomicLoadSub32 : return 28 ; case RISCV :: PseudoMaskedAtomicLoadNand32 : return 32 ; case RISCV :: PseudoMaskedAtomicLoadMax32 : case RISCV :: PseudoMaskedAtomicLoadMin32 : return 44 ; case RISCV :: PseudoMaskedAtomicLoadUMax32 : case RISCV :: PseudoMaskedAtomicLoadUMin32 : return 36 ; case RISCV :: PseudoCmpXchg32 : case RISCV :: PseudoCmpXchg64 : return 16 ; case RISCV :: PseudoMaskedCmpXchg32 : return 32 ; case TargetOpcode :: INLINEASM : case TargetOpcode :: INLINEASM_BR : { const MachineFunction & MF = * MI . getParent ( ) -> getParent ( ) ; const auto & TM = static_cast < const RISCVTargetMachine & > ( MF . getTarget ( ) ) ; return getInlineAsmLength ( MI . getOperand ( 0 ) . getSymbolName ( ) , * TM . getMCAsmInfo ( ) ) ; } } } </s>

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


<s> bool RISCVInstrInfo :: getMemOperandWithOffsetWidth ( const MachineInstr & LdSt , const MachineOperand * & BaseReg , int64_t & Offset , unsigned & Width , const TargetRegisterInfo * TRI ) const { if ( ! LdSt . mayLoadOrStore ( ) ) return false ; if ( LdSt . getNumExplicitOperands ( ) != 3 ) return false ; if ( ! LdSt . getOperand ( 1 ) . isReg ( ) || ! LdSt . getOperand ( 2 ) . isImm ( ) ) return false ; if ( ! LdSt . hasOneMemOperand ( ) ) return false ; Width = ( * LdSt . memoperands_begin ( ) ) -> getSize ( ) ; BaseReg = & LdSt . getOperand ( 1 ) ; Offset = LdSt . getOperand ( 2 ) . getImm ( ) ; return true ; } </s>

Return true if get the base operand , byte offset of an instruction and the memory width .


<s> outliner :: OutlinedFunction RISCVInstrInfo :: getOutliningCandidateInfo ( std :: vector < outliner :: Candidate > & RepeatedSequenceLocs ) const { auto CannotInsertCall = [ ] ( outliner :: Candidate & C ) { const TargetRegisterInfo * TRI = C . getMF ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; C . initLRU ( * TRI ) ; LiveRegUnits LRU = C . LRU ; return ! LRU . available ( RISCV :: X5 ) ; } ; llvm :: erase_if ( RepeatedSequenceLocs , CannotInsertCall ) ; if ( RepeatedSequenceLocs . size ( ) < 2 ) return outliner :: OutlinedFunction ( ) ; unsigned SequenceSize = 0 ; auto I = RepeatedSequenceLocs [ 0 ] . front ( ) ; auto E = std :: next ( RepeatedSequenceLocs [ 0 ] . back ( ) ) ; for ( ; I != E ; ++ I ) SequenceSize += getInstSizeInBytes ( * I ) ; unsigned CallOverhead = 8 ; for ( auto & C : RepeatedSequenceLocs ) C . setCallInfo ( MachineOutlinerDefault , CallOverhead ) ; unsigned FrameOverhead = 4 ; if ( RepeatedSequenceLocs [ 0 ] . getMF ( ) -> getSubtarget ( ) . getFeatureBits ( ) [ RISCV :: FeatureStdExtC ] ) FrameOverhead = 2 ; return outliner :: OutlinedFunction ( RepeatedSequenceLocs , SequenceSize , FrameOverhead , MachineOutlinerDefault ) ; } </s>

Returns a outliner : :OutlinedFunction struct containing target-specific information for a set of outlining candidates .


<s> outliner :: InstrType RISCVInstrInfo :: getOutliningType ( MachineBasicBlock :: iterator & MBBI , unsigned Flags ) const { MachineInstr & MI = * MBBI ; MachineBasicBlock * MBB = MI . getParent ( ) ; const TargetRegisterInfo * TRI = MBB -> getParent ( ) -> getSubtarget ( ) . getRegisterInfo ( ) ; if ( MI . isPosition ( ) ) { if ( MI . isCFIInstruction ( ) ) return outliner :: InstrType :: Invisible ; return outliner :: InstrType :: Illegal ; } if ( MI . isInlineAsm ( ) ) return outliner :: InstrType :: Illegal ; if ( MI . isTerminator ( ) && ! MBB -> succ_empty ( ) ) return outliner :: InstrType :: Illegal ; if ( MI . isReturn ( ) ) return outliner :: InstrType :: Illegal ; if ( MI . modifiesRegister ( RISCV :: X5 , TRI ) || MI . getDesc ( ) . hasImplicitDefOfPhysReg ( RISCV :: X5 ) ) return outliner :: InstrType :: Illegal ; for ( const auto & MO : MI . operands ( ) ) if ( MO . isMBB ( ) || MO . isBlockAddress ( ) || MO . isCPI ( ) ) return outliner :: InstrType :: Illegal ; if ( MI . isMetaInstruction ( ) ) return outliner :: InstrType :: Invisible ; return outliner :: InstrType :: Legal ; } </s>

Returns how or if MIT should be outlined .


Return an array that contains the direct target flag values and their names .

RI5CY RISCV RISCV "riscv-call" "riscv-plt" "riscv-lo" "riscv-hi" "riscv-pcrel-lo" "riscv-pcrel-hi" "riscv-got-hi" "riscv-tprel-lo" "riscv-tprel-hi" "riscv-tprel-add" "riscv-tls-got-hi" "riscv-tls-gd-hi"


"insertBranch must not be told to insert a fallthrough"

"RISCV branch conditions have two components!"

Insert branch code into the end of the specified MachineBasicBlock .


"RegScavenger required for long branching"

"new block should be inserted for expanding unconditional branch"

"Branch offsets outside of the signed 32-bit range not supported"

Insert an unconditional indirect branch at the end of MBB to NewDestBB .


<s> MachineBasicBlock :: iterator RISCVInstrInfo :: insertOutlinedCall ( Module & M , MachineBasicBlock & MBB , MachineBasicBlock :: iterator & It , MachineFunction & MF , const outliner :: Candidate & C ) const { It = MBB . insert ( It , BuildMI ( MF , DebugLoc ( ) , get ( RISCV :: PseudoCALLReg ) , RISCV :: X5 ) . addGlobalAddress ( M . getNamedValue ( MF . getName ( ) ) , 0 , RISCVII :: MO_CALL ) ) ; return It ; } </s>

Insert a call to an outlined function into the program .


<s> bool RISCVInstrInfo :: isAsCheapAsAMove ( const MachineInstr & MI ) const { const unsigned Opcode = MI . getOpcode ( ) ; switch ( Opcode ) { default : break ; case RISCV :: FSGNJ_D : case RISCV :: FSGNJ_S : return MI . getOperand ( 1 ) . isReg ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 1 ) . getReg ( ) == MI . getOperand ( 2 ) . getReg ( ) ; case RISCV :: ADDI : case RISCV :: ORI : case RISCV :: XORI : return ( MI . getOperand ( 1 ) . isReg ( ) && MI . getOperand ( 1 ) . getReg ( ) == RISCV :: X0 ) || ( MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) ; } return MI . isAsCheapAsAMove ( ) ; } </s>

Return true if the instruction is as cheap as a move instruction .


<s>
bool
RISCVInstrInfo
::
isBranchOffsetInRange
(
unsigned
BranchOp
,
int64_t
BrOffset
)
const
{
unsigned
XLen
=
STI
.
getXLen
(
)
;
switch
(
BranchOp
)
{
default
:
llvm_unreachable
(
"Unexpected opcode!"
)
;
case
RISCV
::
BEQ
:
case
RISCV
::
BNE
:
case
RISCV
::
BLT
:
case
RISCV
::
BGE
:
case
RISCV
::
BLTU
:
case
RISCV
::
BGEU
:
case
RISCV
::
P_BEQIMM
:
case
RISCV
::
P_BNEIMM
:
return
isIntN
(
13
,
BrOffset
)
;
case
RISCV
::
JAL
:
case
RISCV
::
PseudoBR
:
return
isIntN
(
21
,
BrOffset
)
;
case
RISCV
::
PseudoJump
:
return
isIntN
(
32
,
SignExtend64
(
BrOffset
+
0x800
,
XLen
)
)
;
}
}
</s>

Determine if the branch target is in range .


<s> Optional < DestSourcePair > RISCVInstrInfo :: isCopyInstrImpl ( const MachineInstr & MI ) const { if ( MI . isMoveReg ( ) ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 1 ) } ; switch ( MI . getOpcode ( ) ) { default : break ; case RISCV :: ADDI : if ( MI . getOperand ( 1 ) . isReg ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 1 ) } ; break ; case RISCV :: FSGNJ_D : case RISCV :: FSGNJ_S : if ( MI . getOperand ( 1 ) . isReg ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 1 ) . getReg ( ) == MI . getOperand ( 2 ) . getReg ( ) ) return DestSourcePair { MI . getOperand ( 0 ) , MI . getOperand ( 1 ) } ; break ; } return None ; } </s>

If the specific machine instruction is a instruction that moves/copies value from one register to another register return destination and source registers as machine operands .


<s> bool RISCVInstrInfo :: isFunctionSafeToOutlineFrom ( MachineFunction & MF , bool OutlineFromLinkOnceODRs ) const { const Function & F = MF . getFunction ( ) ; if ( ! OutlineFromLinkOnceODRs && F . hasLinkOnceODRLinkage ( ) ) return false ; if ( F . hasSection ( ) ) return false ; return true ; } </s>

Return true if the function can safely be outlined from .


<s> unsigned RISCVInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : return 0 ; case RISCV :: LB : case RISCV :: LBU : case RISCV :: LH : case RISCV :: LHU : case RISCV :: FLH : case RISCV :: LW : case RISCV :: FLW : case RISCV :: LWU : case RISCV :: LD : case RISCV :: FLD : break ; } if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { 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> bool RISCVInstrInfo :: isMBBSafeToOutlineFrom ( MachineBasicBlock & MBB , unsigned & Flags ) const { return true ; } </s>

Optional target hook that returns true if MBB is safe to outline from , and returns any target-specific information in Flags .


<s> bool RISCVInstrInfo :: isSchedulingBoundary ( const MachineInstr & MI , const MachineBasicBlock * MBB , const MachineFunction & MF ) const { if ( TargetInstrInfo :: isSchedulingBoundary ( MI , MBB , MF ) ) { return true ; } switch ( MI . getOpcode ( ) ) { case RISCV :: LOOP0setup : case RISCV :: LOOP1setup : case RISCV :: LOOP0setupi : case RISCV :: LOOP1setupi : return true ; default : ; } return false ; } </s>

isSchedulingBoundary - Overrides the isSchedulingBoundary from Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR intructions and prevent it from being re-scheduled .


<s> unsigned RISCVInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : return 0 ; case RISCV :: SB : case RISCV :: SH : case RISCV :: SW : case RISCV :: FSH : case RISCV :: FSW : case RISCV :: SD : case RISCV :: FSD : break ; } if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { 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 .


"Can't load this register from stack slot"

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


<s> unsigned RISCVInstrInfo :: removeBranch ( MachineBasicBlock & MBB , int * BytesRemoved ) const { if ( BytesRemoved ) * BytesRemoved = 0 ; MachineBasicBlock :: iterator I = MBB . getLastNonDebugInstr ( ) ; if ( I == MBB . end ( ) ) return 0 ; if ( ! I -> getDesc ( ) . isUnconditionalBranch ( ) && ! I -> getDesc ( ) . isConditionalBranch ( ) ) return 0 ; if ( BytesRemoved ) * BytesRemoved += getInstSizeInBytes ( * I ) ; I -> eraseFromParent ( ) ; I = MBB . end ( ) ; if ( I == MBB . begin ( ) ) return 1 ; -- I ; if ( ! I -> getDesc ( ) . isConditionalBranch ( ) ) return 1 ; if ( BytesRemoved ) * BytesRemoved += getInstSizeInBytes ( * I ) ; I -> eraseFromParent ( ) ; return 2 ; } </s>

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


<s>
bool
RISCVInstrInfo
::
reverseBranchCondition
(
SmallVectorImpl
<
MachineOperand
>
&
Cond
)
const
{
assert
(
(
Cond
.
size
(
)
==
3
)
&&
"Invalid branch condition!"
)
;
Cond
[
0
]
.
setImm
(
getOppositeBranchOpcode
(
Cond
[
0
]
.
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 .


"Can't store this register to stack slot"

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


<s>
bool
RISCVInstrInfo
::
verifyInstruction
(
const
MachineInstr
&
MI
,
StringRef
&
ErrInfo
)
const
{
const
MCInstrInfo
*
MCII
=
STI
.
getInstrInfo
(
)
;
MCInstrDesc
const
&
Desc
=
MCII
->
get
(
MI
.
getOpcode
(
)
)
;
for
(
auto
&
OI
:
enumerate
(
Desc
.
operands
(
)
)
)
{
unsigned
OpType
=
OI
.
value
(
)
.
OperandType
;
if
(
OpType
>=
RISCVOp
::
OPERAND_FIRST_RISCV_IMM
&&
OpType
<=
RISCVOp
::
OPERAND_LAST_RISCV_IMM
)
{
const
MachineOperand
&
MO
=
MI
.
getOperand
(
OI
.
index
(
)
)
;
if
(
MO
.
isImm
(
)
)
{
int64_t
Imm
=
MO
.
getImm
(
)
;
bool
Ok
;
switch
(
OpType
)
{
default
:
llvm_unreachable
(
"Unexpected operand type"
)
;
case
RISCVOp
::
OPERAND_UIMM4
:
Ok
=
isUInt
<
4
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_UIMM5
:
Ok
=
isUInt
<
5
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_UIMM12
:
Ok
=
isUInt
<
12
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_UIMM12M1
:
Ok
=
isUInt
<
12
>
(
Imm
)
&&
(
Imm
!=
0
)
;
break
;
case
RISCVOp
::
OPERAND_UIMM3
:
Ok
=
isUInt
<
3
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_SIMM12
:
Ok
=
isInt
<
12
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_UIMM20
:
Ok
=
isUInt
<
20
>
(
Imm
)
;
break
;
case
RISCVOp
::
OPERAND_UIMMLOG2XLEN
:
if
(
STI
.
getTargetTriple
(
)
.
isArch64Bit
(
)
)
Ok
=
isUInt
<
6
>
(
Imm
)
;
else
Ok
=
isUInt
<
5
>
(
Imm
)
;
break
;
}
if
(
!
Ok
)
{
ErrInfo
=
"Invalid immediate"
;
return
false
;
}
}
}
}
return
true
;
}
</s>

Perform target-specific instruction verification .


<s> static const char * getName ( ) { return DEBUG_TYPE ; } </s>

Return a string with the name of the plan and the applicable VFs and UFs .


<s> bool RISCVInstructionSelector :: select ( MachineInstr & I ) { if ( ! isPreISelGenericOpcode ( I . getOpcode ( ) ) ) { return true ; } if ( selectImpl ( I , * CoverageInfo ) ) return true ; return false ; } </s>

Select the ( possibly generic ) instruction I to only use target-specific opcodes .


"RISCV DAG->DAG Pattern Instruction Selection"

getPassName - Return a nice clean name for a pass .


<s> void RISCVDAGToDAGISel :: PostprocessISelDAG ( ) { doPeepholeLoadStoreADDI ( ) ; } </s>

PostprocessISelDAG ( ) - This hook allows the target to hack on the graph right after selection .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { Subtarget = & MF . getSubtarget < RISCVSubtarget > ( ) ; return SelectionDAGISel :: runOnMachineFunction ( MF ) ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool RISCVDAGToDAGISel :: SelectInlineAsmMemoryOperand ( const SDValue & Op , unsigned ConstraintID , std :: vector < SDValue > & OutOps ) { switch ( ConstraintID ) { case InlineAsm :: Constraint_m : OutOps . push_back ( Op ) ; return false ; case InlineAsm :: Constraint_A : OutOps . push_back ( Op ) ; return false ; default : break ; } return true ; } </s>

SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode , according to the specified constraint .


<s> bool RISCVTargetLowering :: allowsMisalignedMemoryAccesses ( EVT VT , unsigned AddrSpace = 0 , unsigned Align = 1 , MachineMemOperand :: Flags Flags = MachineMemOperand :: MONone , bool * Fast = nullptr ) const { if ( Subtarget . hasPULPExtV2 ( ) ) { if ( Fast ) { * Fast = false ; } return true ; } return false ; } </s>

Returns true if the target allows unaligned memory accesses of the specified type .


<s> bool RISCVTargetLowering :: 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 ) ; Optional < unsigned > FirstMaskArgument ; if ( Subtarget . hasStdExtV ( ) ) FirstMaskArgument = preAssignMask ( Outs ) ; for ( unsigned i = 0 , e = Outs . size ( ) ; i != e ; ++ i ) { MVT VT = Outs [ i ] . VT ; ISD :: ArgFlagsTy ArgFlags = Outs [ i ] . Flags ; RISCVABI :: ABI ABI = MF . getSubtarget < RISCVSubtarget > ( ) . getTargetABI ( ) ; if ( CC_RISCV ( MF . getDataLayout ( ) , ABI , i , VT , VT , CCValAssign :: Full , ArgFlags , CCInfo , true , true , nullptr , * this , FirstMaskArgument ) ) 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 .

RI5CY RISCV ISD::OutputArg 16 0 ISD::ArgFlagsTy RISCVABI::ABI RISCV RISCV


"Should use MaskedValueIsZero if you don't know whether Op"

Determine which of the bits specified in Mask are known to be either zero or one and return them in the KnownZero/KnownOne bitsets .


<s> unsigned RISCVTargetLowering :: ComputeNumSignBitsForTargetNode ( SDValue Op , const APInt & DemandedElts , const SelectionDAG & DAG , unsigned Depth ) const { switch ( Op . getOpcode ( ) ) { default : break ; case RISCVISD :: SLLW : case RISCVISD :: SRAW : case RISCVISD :: SRLW : case RISCVISD :: DIVW : case RISCVISD :: DIVUW : case RISCVISD :: REMUW : case RISCVISD :: ROLW : case RISCVISD :: RORW : case RISCVISD :: GREVIW : case RISCVISD :: GORCIW : case RISCVISD :: FSLW : case RISCVISD :: FSRW : return 33 ; case RISCVISD :: VMV_X_S : if ( Op . getOperand ( 0 ) . getScalarValueSizeInBits ( ) > Subtarget . getXLen ( ) ) return 1 ; return Subtarget . getXLen ( ) - Op . getOperand ( 0 ) . getScalarValueSizeInBits ( ) + 1 ; } return 1 ; } </s>

Determine the number of bits in the operation that are sign bits .


<s> bool convertSelectOfConstantsToMath ( EVT VT ) const override { return true ; } </s>

Return true if a select of constants ( select Cond , C1 , C2 ) should be transformed into simple math ops with the condition value .


<s> bool convertSetCCLogicToBitwiseLogic ( EVT VT ) const override { return VT . isScalarInteger ( ) ; } </s>

Use bitwise logic to make pairs of compares more efficient .


<s> bool RISCVTargetLowering :: decomposeMulByConstant ( LLVMContext & Context , EVT VT , SDValue C ) const { if ( VT . isScalarInteger ( ) ) { if ( Subtarget . hasStdExtM ( ) && VT . getSizeInBits ( ) > Subtarget . getXLen ( ) ) return false ; if ( auto * ConstNode = dyn_cast < ConstantSDNode > ( C . getNode ( ) ) ) { const APInt & Imm = ConstNode -> getAPIntValue ( ) ; if ( ( Imm + 1 ) . isPowerOf2 ( ) || ( Imm - 1 ) . isPowerOf2 ( ) || ( 1 - Imm ) . isPowerOf2 ( ) || ( - 1 - Imm ) . isPowerOf2 ( ) ) return true ; if ( Subtarget . hasStdExtM ( ) && VT . getSizeInBits ( ) >= Subtarget . getXLen ( ) ) return false ; if ( ! Imm . isSignedIntN ( 12 ) && Imm . countTrailingZeros ( ) < 12 ) { APInt ImmS = Imm . ashr ( Imm . countTrailingZeros ( ) ) ; if ( ( ImmS + 1 ) . isPowerOf2 ( ) || ( ImmS - 1 ) . isPowerOf2 ( ) || ( 1 - ImmS ) . isPowerOf2 ( ) ) return true ; } } } return false ; } </s>

Return true if it is profitable to transform an integer multiplication-by-constant into simpler operations like shifts and adds .


"ReadCycleWrite is only to be used on riscv32"

This method should be implemented by targets that mark instructions with the 'usesCustomInserter ' flag .


<s> Instruction * RISCVTargetLowering :: emitLeadingFence ( IRBuilder < > & Builder , Instruction * Inst , AtomicOrdering Ord ) const { if ( isa < LoadInst > ( Inst ) && Ord == AtomicOrdering :: SequentiallyConsistent ) return Builder . CreateFence ( Ord ) ; if ( isa < StoreInst > ( Inst ) && isReleaseOrStronger ( Ord ) ) return Builder . CreateFence ( AtomicOrdering :: Release ) ; return nullptr ; } </s>


<s> Value * RISCVTargetLowering :: emitMaskedAtomicCmpXchgIntrinsic ( IRBuilder < > & Builder , AtomicCmpXchgInst * CI , Value * AlignedAddr , Value * CmpVal , Value * NewVal , Value * Mask , AtomicOrdering Ord ) const { unsigned XLen = Subtarget . getXLen ( ) ; Value * Ordering = Builder . getIntN ( XLen , static_cast < uint64_t > ( Ord ) ) ; Intrinsic :: ID CmpXchgIntrID = Intrinsic :: riscv_masked_cmpxchg_i32 ; if ( XLen == 64 ) { CmpVal = Builder . CreateSExt ( CmpVal , Builder . getInt64Ty ( ) ) ; NewVal = Builder . CreateSExt ( NewVal , Builder . getInt64Ty ( ) ) ; Mask = Builder . CreateSExt ( Mask , Builder . getInt64Ty ( ) ) ; CmpXchgIntrID = Intrinsic :: riscv_masked_cmpxchg_i64 ; } Type * Tys [ ] = { AlignedAddr -> getType ( ) } ; Function * MaskedCmpXchg = Intrinsic :: getDeclaration ( CI -> getModule ( ) , CmpXchgIntrID , Tys ) ; Value * Result = Builder . CreateCall ( MaskedCmpXchg , { AlignedAddr , CmpVal , NewVal , Mask , Ordering } ) ; if ( XLen == 64 ) Result = Builder . CreateTrunc ( Result , Builder . getInt32Ty ( ) ) ; return Result ; } </s>

Perform a masked cmpxchg using a target-specific intrinsic .


<s> Value * RISCVTargetLowering :: emitMaskedAtomicRMWIntrinsic ( IRBuilder < > & Builder , AtomicRMWInst * AI , Value * AlignedAddr , Value * Incr , Value * Mask , Value * ShiftAmt , AtomicOrdering Ord ) const { unsigned XLen = Subtarget . getXLen ( ) ; Value * Ordering = Builder . getIntN ( XLen , static_cast < uint64_t > ( AI -> getOrdering ( ) ) ) ; Type * Tys [ ] = { AlignedAddr -> getType ( ) } ; Function * LrwOpScwLoop = Intrinsic :: getDeclaration ( AI -> getModule ( ) , getIntrinsicForMaskedAtomicRMWBinOp ( XLen , AI -> getOperation ( ) ) , Tys ) ; if ( XLen == 64 ) { Incr = Builder . CreateSExt ( Incr , Builder . getInt64Ty ( ) ) ; Mask = Builder . CreateSExt ( Mask , Builder . getInt64Ty ( ) ) ; ShiftAmt = Builder . CreateSExt ( ShiftAmt , Builder . getInt64Ty ( ) ) ; } Value * Result ; if ( AI -> getOperation ( ) == AtomicRMWInst :: Min || AI -> getOperation ( ) == AtomicRMWInst :: Max ) { const DataLayout & DL = AI -> getModule ( ) -> getDataLayout ( ) ; unsigned ValWidth = DL . getTypeStoreSizeInBits ( AI -> getValOperand ( ) -> getType ( ) ) ; Value * SextShamt = Builder . CreateSub ( Builder . getIntN ( XLen , XLen - ValWidth ) , ShiftAmt ) ; Result = Builder . CreateCall ( LrwOpScwLoop , { AlignedAddr , Incr , Mask , SextShamt , Ordering } ) ; } else { Result = Builder . CreateCall ( LrwOpScwLoop , { AlignedAddr , Incr , Mask , Ordering } ) ; } if ( XLen == 64 ) Result = Builder . CreateTrunc ( Result , Builder . getInt32Ty ( ) ) ; return Result ; } </s>

Perform a masked atomicrmw using a target-specific intrinsic .


<s>
SDValue
RISCVTargetLowering
::
getAddr
(
NodeTy
*
N
,
SelectionDAG
&
DAG
,
bool
IsLocal
)
const
{
SDLoc
DL
(
N
)
;
EVT
Ty
=
getPointerTy
(
DAG
.
getDataLayout
(
)
)
;
if
(
isPositionIndependent
(
)
)
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
if
(
IsLocal
)
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
}
switch
(
getTargetMachine
(
)
.
getCodeModel
(
)
)
{
default
:
report_fatal_error
(
"Unsupported code model for lowering"
)
;
case
CodeModel
::
Small
:
{
SDValue
AddrHi
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_HI
)
;
SDValue
AddrLo
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
RISCVII
::
MO_LO
)
;
SDValue
MNHi
=
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
LUI
,
DL
,
Ty
,
AddrHi
)
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
ADDI
,
DL
,
Ty
,
MNHi
,
AddrLo
)
,
0
)
;
}
case
CodeModel
::
Medium
:
{
SDValue
Addr
=
getTargetNode
(
N
,
DL
,
Ty
,
DAG
,
0
)
;
return
SDValue
(
DAG
.
getMachineNode
(
RISCV
::
PseudoLLA
,
DL
,
Ty
,
Addr
)
,
0
)
;
}
}
}
</s>

Return the address accessed by this recipe .


<s> RISCVTargetLowering :: ConstraintType RISCVTargetLowering :: getConstraintType ( StringRef Constraint ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { default : break ; case 'f' : return C_RegisterClass ; case 'I' : case 'J' : case 'K' : return C_Immediate ; case 'A' : return C_Memory ; } } return TargetLowering :: getConstraintType ( Constraint ) ; } </s>

Given a constraint letter , return the type of constraint for this target .


<s> Register RISCVTargetLowering :: getExceptionPointerRegister ( const Constant * PersonalityFn ) const { return RISCV :: X10 ; } </s>

If a physical register , this returns the register that receives the exception address on entry to an EH pad .


<s> Register RISCVTargetLowering :: getExceptionSelectorRegister ( const Constant * PersonalityFn ) const { return RISCV :: X11 ; } </s>

If a physical register , this returns the register that receives the exception typeid on entry to a landing pad .


<s> ISD :: NodeType getExtendForAtomicCmpSwapArg ( ) const override { return ISD :: SIGN_EXTEND ; } </s>

Returns how the platform 's atomic compare and swap expects its comparison value to be extended ( ZERO_EXTEND , SIGN_EXTEND , or ANY_EXTEND ) .


<s> ISD :: NodeType getExtendForAtomicOps ( ) const override { return ISD :: SIGN_EXTEND ; } </s>

Returns how the platform 's atomic operations are extended ( ZERO_EXTEND , SIGN_EXTEND , or ANY_EXTEND ) .


<s> MVT RISCVTargetLowering :: getPointerMemTy ( const DataLayout & DL , uint32_t AS ) const { if ( AS == UINT32_MAX ) { AS = 0 ; } return MVT :: getIntegerVT ( DL . getPointerSizeInBits ( AS ) ) ; } </s>

Return the in-memory pointer type for the given address space , defaults to the pointer type from the data layout .


<s> MVT RISCVTargetLowering :: getPointerTy ( const DataLayout & DL , uint32_t AS ) const { if ( AS == UINT32_MAX ) { AS = 0 ; } return MVT :: getIntegerVT ( DL . getPointerSizeInBits ( AS ) ) ; } </s>

Return the pointer type for the given address space , defaults to the pointer type from the data layout .


<s> bool RISCVTargetLowering :: getPostIndexedAddressParts ( SDNode * N , SDNode * Op , SDValue & Base , SDValue & Offset , ISD :: MemIndexedMode & AM , SelectionDAG & DAG ) const { SDValue BaseFromLDST ; EVT VT ; if ( LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { BaseFromLDST = LD -> getBasePtr ( ) ; VT = LD -> getMemoryVT ( ) ; } else if ( StoreSDNode * ST = dyn_cast < StoreSDNode > ( N ) ) { BaseFromLDST = ST -> getBasePtr ( ) ; VT = ST -> getMemoryVT ( ) ; } else { return false ; } if ( Op -> getOpcode ( ) == ISD :: ADD ) { AM = ISD :: POST_INC ; Base = Op -> getOperand ( 0 ) ; Offset = Op -> getOperand ( 1 ) ; if ( BaseFromLDST != Base && BaseFromLDST == Offset ) { std :: swap ( Base , Offset ) ; } if ( ! ( VT == MVT :: i8 || VT == MVT :: i16 || VT == MVT :: i32 ) ) { return false ; } if ( ConstantSDNode * ConstOffset = dyn_cast < ConstantSDNode > ( Offset ) ) { uint64_t imm = ConstOffset -> getZExtValue ( ) ; if ( ! isInt < 12 > ( imm ) ) { return false ; } } return BaseFromLDST == Base ; } return false ; } </s>

Returns true by value , base pointer and offset pointer and addressing mode by reference if this node can be combined with a load / store to form a post-indexed load / store .


"Trying to obtain non-reserved register \""

Return the register ID of the name passed in .


<s> MVT RISCVTargetLowering :: getScalarShiftAmountTy ( const DataLayout & DL , EVT ) const { return Subtarget . getXLenVT ( ) ; } </s>

Return the type to use for a scalar shift opcode , given the shifted amount type .


<s> EVT RISCVTargetLowering :: getSetCCResultType ( const DataLayout & DL , LLVMContext & , EVT VT ) const { if ( ! VT . isVector ( ) ) return getPointerTy ( DL ) ; if ( Subtarget . hasStdExtV ( ) ) return MVT :: getVectorVT ( MVT :: i1 , VT . getVectorElementCount ( ) ) ; return VT . changeVectorElementTypeToInteger ( ) ; } </s>

Return the value type to use for ISD : :SETCC .


<s> const RISCVSubtarget & getSubtarget ( ) const { return Subtarget ; } </s>

getSubtarget - Return the subtarget for which this machine code is being compiled .


<s> static SDValue getTargetNode ( JumpTableSDNode * N , SDLoc DL , EVT Ty , SelectionDAG & DAG , unsigned Flags ) { return DAG . getTargetJumpTable ( N -> getIndex ( ) , Ty , Flags ) ; } </s>

Retrieve the target node this edge connects to .


<s> const char * RISCVTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { case RISCVISD :: NODE : \ return "RISCVISD::" # NODE ; switch ( ( RISCVISD :: NodeType ) Opcode ) { case RISCVISD :: FIRST_NUMBER : break ; NODE_NAME_CASE ( RET_FLAG ) NODE_NAME_CASE ( URET_FLAG ) NODE_NAME_CASE ( SRET_FLAG ) NODE_NAME_CASE ( MRET_FLAG ) NODE_NAME_CASE ( CALL ) NODE_NAME_CASE ( SELECT_CC ) NODE_NAME_CASE ( BuildPairF64 ) NODE_NAME_CASE ( SplitF64 ) NODE_NAME_CASE ( TAIL ) NODE_NAME_CASE ( SLLW ) NODE_NAME_CASE ( SRAW ) NODE_NAME_CASE ( SRLW ) NODE_NAME_CASE ( DIVW ) NODE_NAME_CASE ( DIVUW ) NODE_NAME_CASE ( REMUW ) NODE_NAME_CASE ( ROLW ) NODE_NAME_CASE ( RORW ) NODE_NAME_CASE ( FSLW ) NODE_NAME_CASE ( FSRW ) NODE_NAME_CASE ( FMV_H_X ) NODE_NAME_CASE ( FMV_X_ANYEXTH ) NODE_NAME_CASE ( FMV_W_X_RV64 ) NODE_NAME_CASE ( FMV_X_ANYEXTW_RV64 ) NODE_NAME_CASE ( READ_CYCLE_WIDE ) NODE_NAME_CASE ( GREVI ) NODE_NAME_CASE ( GREVIW ) NODE_NAME_CASE ( GORCI ) NODE_NAME_CASE ( GORCIW ) NODE_NAME_CASE ( VMV_X_S ) NODE_NAME_CASE ( SPLAT_VECTOR_I64 ) NODE_NAME_CASE ( READ_VLENB ) NODE_NAME_CASE ( TRUNCATE_VECTOR ) NODE_NAME_CASE ( VLEFF ) NODE_NAME_CASE ( VLEFF_MASK ) NODE_NAME_CASE ( VLSEGFF ) NODE_NAME_CASE ( VLSEGFF_MASK ) NODE_NAME_CASE ( READ_VL ) NODE_NAME_CASE ( VSLIDEUP ) NODE_NAME_CASE ( VSLIDEDOWN ) NODE_NAME_CASE ( VID ) } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific

RI5CY RISCV RISCVISD::NODE "RISCVISD::" RISCVISD::NodeType RISCVISD::FIRST_NUMBER


<s> bool RISCVTargetLowering :: getTgtMemIntrinsic ( IntrinsicInfo & Info , const CallInst & I , MachineFunction & MF , unsigned Intrinsic ) const { switch ( Intrinsic ) { default : return false ; case Intrinsic :: riscv_masked_atomicrmw_xchg_i32 : case Intrinsic :: riscv_masked_atomicrmw_add_i32 : case Intrinsic :: riscv_masked_atomicrmw_sub_i32 : case Intrinsic :: riscv_masked_atomicrmw_nand_i32 : case Intrinsic :: riscv_masked_atomicrmw_max_i32 : case Intrinsic :: riscv_masked_atomicrmw_min_i32 : case Intrinsic :: riscv_masked_atomicrmw_umax_i32 : case Intrinsic :: riscv_masked_atomicrmw_umin_i32 : case Intrinsic :: riscv_masked_cmpxchg_i32 : PointerType * PtrTy = cast < PointerType > ( I . getArgOperand ( 0 ) -> getType ( ) ) ; Info . opc = ISD :: INTRINSIC_W_CHAIN ; Info . memVT = MVT :: getVT ( PtrTy -> getElementType ( ) ) ; Info . ptrVal = I . getArgOperand ( 0 ) ; Info . offset = 0 ; Info . align = Align ( 4 ) ; Info . flags = MachineMemOperand :: MOLoad | MachineMemOperand :: MOStore | MachineMemOperand :: MOVolatile ; return true ; } } </s>

Given an intrinsic , checks if on the target the intrinsic will need to map to a MemIntrinsicNode ( touches memory ) .


<s> bool RISCVTargetLowering :: isCheapToSpeculateCtlz ( ) const { return Subtarget . hasStdExtZbb ( ) ; } </s>

Return true if it is cheap to speculate a call to intrinsic ctlz .


<s> bool RISCVTargetLowering :: isCheapToSpeculateCttz ( ) const { return Subtarget . hasStdExtZbb ( ) ; } </s>

Return true if it is cheap to speculate a call to intrinsic cttz .


<s> bool RISCVTargetLowering :: isDesirableToCommuteWithShift ( const SDNode * N , CombineLevel Level ) const { SDValue N0 = N -> getOperand ( 0 ) ; EVT Ty = N0 . getValueType ( ) ; if ( Ty . isScalarInteger ( ) && ( N0 . getOpcode ( ) == ISD :: ADD || N0 . getOpcode ( ) == ISD :: OR ) ) { auto * C1 = dyn_cast < ConstantSDNode > ( N0 -> getOperand ( 1 ) ) ; auto * C2 = dyn_cast < ConstantSDNode > ( N -> getOperand ( 1 ) ) ; if ( C1 && C2 ) { const APInt & C1Int = C1 -> getAPIntValue ( ) ; APInt ShiftedC1Int = C1Int << C2 -> getAPIntValue ( ) ; if ( ShiftedC1Int . getMinSignedBits ( ) <= 64 && isLegalAddImmediate ( ShiftedC1Int . getSExtValue ( ) ) ) return true ; if ( C1Int . getMinSignedBits ( ) <= 64 && isLegalAddImmediate ( C1Int . getSExtValue ( ) ) ) return false ; int C1Cost = RISCVMatInt :: getIntMatCost ( C1Int , Ty . getSizeInBits ( ) , Subtarget . is64Bit ( ) ) ; int ShiftedC1Cost = RISCVMatInt :: getIntMatCost ( ShiftedC1Int , Ty . getSizeInBits ( ) , Subtarget . is64Bit ( ) ) ; if ( C1Cost < ShiftedC1Cost ) return false ; } } return true ; } </s>

Return true if it is profitable to move this shift by a constant amount through its operand , adjusting any immediate operands as necessary to preserve semantics .


<s> bool RISCVTargetLowering :: isEligibleForTailCallOptimization ( CCState & CCInfo , CallLoweringInfo & CLI , MachineFunction & MF , const SmallVector < CCValAssign , 16 > & ArgLocs ) const { auto & Callee = CLI . Callee ; auto CalleeCC = CLI . CallConv ; auto & Outs = CLI . Outs ; auto & Caller = MF . getFunction ( ) ; auto CallerCC = Caller . getCallingConv ( ) ; if ( Caller . hasFnAttribute ( "interrupt" ) ) return false ; if ( CCInfo . getNextStackOffset ( ) != 0 ) return false ; for ( auto & VA : ArgLocs ) if ( VA . getLocInfo ( ) == CCValAssign :: Indirect ) return false ; auto IsCallerStructRet = Caller . hasStructRetAttr ( ) ; auto IsCalleeStructRet = Outs . empty ( ) ? false : Outs [ 0 ] . Flags . isSRet ( ) ; if ( IsCallerStructRet || IsCalleeStructRet ) return false ; if ( GlobalAddressSDNode * G = dyn_cast < GlobalAddressSDNode > ( Callee ) ) { const GlobalValue * GV = G -> getGlobal ( ) ; if ( GV -> hasExternalWeakLinkage ( ) ) return false ; } const RISCVRegisterInfo * TRI = Subtarget . getRegisterInfo ( ) ; const uint32_t * CallerPreserved = TRI -> getCallPreservedMask ( MF , CallerCC ) ; if ( CalleeCC != CallerCC ) { const uint32_t * CalleePreserved = TRI -> getCallPreservedMask ( MF , CalleeCC ) ; if ( ! TRI -> regmaskSubsetEqual ( CallerPreserved , CalleePreserved ) ) return false ; } for ( auto & Arg : Outs ) if ( Arg . Flags . isByVal ( ) ) return false ; return true ; } </s>

Returns true if the call can be lowered as a tail call .


<s> bool RISCVTargetLowering :: isFMAFasterThanFMulAndFAdd ( const MachineFunction & MF , EVT VT ) const { VT = VT . getScalarType ( ) ; if ( ! VT . isSimple ( ) ) return false ; switch ( VT . getSimpleVT ( ) . SimpleTy ) { case MVT :: f16 : return Subtarget . hasStdExtZfh ( ) ; case MVT :: f32 : return Subtarget . hasStdExtF ( ) ; case MVT :: f64 : return Subtarget . hasStdExtD ( ) ; default : break ; } return false ; } </s>

Return true if an FMA operation is faster than a pair of fmul and fadd instructions .


<s> bool RISCVTargetLowering :: isFPImmLegal ( const APFloat & Imm , EVT VT , bool ForCodeSize ) const { if ( VT == MVT :: f16 && ! Subtarget . hasStdExtZfh ( ) ) return false ; if ( VT == MVT :: f32 && ! Subtarget . hasStdExtF ( ) ) return false ; if ( VT == MVT :: f64 && ! Subtarget . hasStdExtD ( ) ) return false ; if ( Imm . isNegZero ( ) ) return false ; return Imm . isZero ( ) ; } </s>

Returns true if the target can instruction select the specified FP immediate natively .


<s> bool RISCVTargetLowering :: isLegalAddImmediate ( int64_t Imm ) const { return isInt < 12 > ( Imm ) ; } </s>

Return true if the specified immediate is legal add immediate , that is the target has add instructions which can add a register and the immediate without having to materialize the immediate into a register .


<s> bool RISCVTargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS , Instruction * I ) const { if ( AM . BaseGV ) return false ; if ( ! isInt < 12 > ( AM . BaseOffs ) ) return false ; switch ( AM . Scale ) { case 0 : break ; case 1 : if ( ! AM . HasBaseReg ) break ; return false ; default : return false ; } return true ; } </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> bool RISCVTargetLowering :: isLegalICmpImmediate ( int64_t Imm ) const { return isInt < 12 > ( Imm ) ; } </s>

Return true if the specified immediate is legal icmp immediate , that is the target has icmp instructions which can compare a register against the immediate without having to materialize the immediate into a register .


<s> bool RISCVTargetLowering :: isSExtCheaperThanZExt ( EVT SrcVT , EVT DstVT ) const { return Subtarget . is64Bit ( ) && SrcVT == MVT :: i32 && DstVT == MVT :: i64 ; } </s>

Return true if sign-extension from FromTy to ToTy is cheaper than zero-extension .


<s> bool RISCVTargetLowering :: isTruncateFree ( EVT SrcVT , EVT DstVT ) const { if ( Subtarget . is64Bit ( ) || SrcVT . isVector ( ) || DstVT . isVector ( ) || ! SrcVT . isInteger ( ) || ! DstVT . isInteger ( ) ) return false ; unsigned SrcBits = SrcVT . getSizeInBits ( ) ; unsigned DestBits = DstVT . getSizeInBits ( ) ; return ( SrcBits == 64 && DestBits == 32 ) ; } </s>

Return true if it 's free to truncate a value of type Ty1 to type Ty2 .


<s> bool RISCVTargetLowering :: isZExtFree ( SDValue Val , EVT VT2 ) const { if ( auto * LD = dyn_cast < LoadSDNode > ( Val ) ) { EVT MemVT = LD -> getMemoryVT ( ) ; if ( ( MemVT == MVT :: i8 || MemVT == MVT :: i16 || ( Subtarget . is64Bit ( ) && MemVT == MVT :: i32 ) ) && ( LD -> getExtensionType ( ) == ISD :: NON_EXTLOAD || LD -> getExtensionType ( ) == ISD :: ZEXTLOAD ) ) return true ; } return TargetLowering :: isZExtFree ( Val , VT2 ) ; } </s>

Return true if zero-extending the specific node Val to type VT2 is free ( either because it 's implicitly zero-extended such as ARM ldrb / ldrh or because it 's folded such as X86 zero-extending loads ) .


<s> void RISCVTargetLowering :: LowerAsmOperandForConstraint ( SDValue Op , std :: string & Constraint , std :: vector < SDValue > & Ops , SelectionDAG & DAG ) const { if ( Constraint . length ( ) == 1 ) { switch ( Constraint [ 0 ] ) { case 'I' : if ( auto * C = dyn_cast < ConstantSDNode > ( Op ) ) { uint64_t CVal = C -> getSExtValue ( ) ; if ( isInt < 12 > ( CVal ) ) Ops . push_back ( DAG . getTargetConstant ( CVal , SDLoc ( Op ) , Subtarget . getXLenVT ( ) ) ) ; } return ; case 'J' : if ( auto * C = dyn_cast < ConstantSDNode > ( Op ) ) if ( C -> getZExtValue ( ) == 0 ) Ops . push_back ( DAG . getTargetConstant ( 0 , SDLoc ( Op ) , Subtarget . getXLenVT ( ) ) ) ; return ; case 'K' : if ( auto * C = dyn_cast < ConstantSDNode > ( Op ) ) { uint64_t CVal = C -> getZExtValue ( ) ; if ( isUInt < 5 > ( CVal ) ) Ops . push_back ( DAG . getTargetConstant ( CVal , SDLoc ( Op ) , Subtarget . getXLenVT ( ) ) ) ; } return ; default : break ; } } TargetLowering :: LowerAsmOperandForConstraint ( Op , Constraint , Ops , DAG ) ; } </s>

Lower the specified operand into the Ops vector .


<s> bool RISCVTargetLowering :: mayBeEmittedAsTailCall ( const CallInst * CI ) const { return CI -> isTailCall ( ) ; } </s>

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


<s> bool shouldConvertConstantLoadToIntImm ( const APInt & Imm , Type * Ty ) const override { return true ; } </s>

Returns true if it is beneficial to convert a load of a constant to just the constant itself .


<s> TargetLowering :: AtomicExpansionKind RISCVTargetLowering :: shouldExpandAtomicCmpXchgInIR ( AtomicCmpXchgInst * CI ) const { unsigned Size = CI -> getCompareOperand ( ) -> getType ( ) -> getPrimitiveSizeInBits ( ) ; if ( Size == 8 || Size == 16 ) return AtomicExpansionKind :: MaskedIntrinsic ; return AtomicExpansionKind :: None ; } </s>

Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass .


<s> TargetLowering :: AtomicExpansionKind RISCVTargetLowering :: shouldExpandAtomicRMWInIR ( AtomicRMWInst * AI ) const { if ( AI -> isFloatingPointOperation ( ) ) return AtomicExpansionKind :: CmpXChg ; unsigned Size = AI -> getType ( ) -> getPrimitiveSizeInBits ( ) ; if ( Size == 8 || Size == 16 ) return AtomicExpansionKind :: MaskedIntrinsic ; return AtomicExpansionKind :: None ; } </s>

Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW , if at all .


<s> bool RISCVTargetLowering :: shouldExtendTypeInLibCall ( EVT Type ) const { RISCVABI :: ABI ABI = Subtarget . getTargetABI ( ) ; if ( ABI == RISCVABI :: ABI_LP64 && ( Type == MVT :: f32 ) ) return false ; return true ; } </s>

Returns true if arguments should be extended in lib calls .


<s> bool shouldInsertFencesForAtomic ( const Instruction * I ) const override { return isa < LoadInst > ( I ) || isa < StoreInst > ( I ) ; } </s>

Helper functions for atomic operations .


<s> bool RISCVTargetLowering :: shouldSignExtendTypeInLibCall ( EVT Type , bool IsSigned ) const { if ( Subtarget . is64Bit ( ) && Type == MVT :: i32 ) return true ; return IsSigned ; } </s>

Returns true if arguments should be sign-extended in lib calls .


<s>
void
RISCVMCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
verifyInstructionPredicates
(
MI
,
computeAvailableFeatures
(
STI
.
getFeatureBits
(
)
)
)
;
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
MI
.
getOpcode
(
)
)
;
unsigned
Size
=
Desc
.
getSize
(
)
;
if
(
MI
.
getOpcode
(
)
==
RISCV
::
PseudoCALLReg
||
MI
.
getOpcode
(
)
==
RISCV
::
PseudoCALL
||
MI
.
getOpcode
(
)
==
RISCV
::
PseudoTAIL
||
MI
.
getOpcode
(
)
==
RISCV
::
PseudoJump
)
{
expandFunctionCall
(
MI
,
OS
,
Fixups
,
STI
)
;
MCNumEmitted
+=
2
;
return
;
}
if
(
MI
.
getOpcode
(
)
==
RISCV
::
PseudoAddTPRel
)
{
expandAddTPRel
(
MI
,
OS
,
Fixups
,
STI
)
;
MCNumEmitted
+=
1
;
return
;
}
switch
(
Size
)
{
default
:
llvm_unreachable
(
"Unhandled encodeInstruction length!"
)
;
case
2
:
{
uint16_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
support
::
endian
::
write
<
uint16_t
>
(
OS
,
Bits
,
support
::
little
)
;
break
;
}
case
4
:
{
uint32_t
Bits
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
support
::
endian
::
write
(
OS
,
Bits
,
support
::
little
)
;
break
;
}
}
++
MCNumEmitted
;
}
</s>

Encode the given Inst to bytes and append to CB .

RI5CY
RISCV
RISCV::PseudoCALLReg
RISCV::PseudoCALL
RISCV::PseudoTAIL
RISCV::PseudoJump
2
RISCV::PseudoAddTPRel
1
"Unhandled encodeInstruction length!"
2
support::endian
support::little
4
support::endian
support::little


<s>
unsigned
RISCVMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
if
(
MO
.
isReg
(
)
)
return
Ctx
.
getRegisterInfo
(
)
->
getEncodingValue
(
MO
.
getReg
(
)
)
;
if
(
MO
.
isImm
(
)
)
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
if
(
MO
.
isExpr
(
)
&&
(
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0setup
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1setup
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0setupi
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1setupi
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0starti
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1starti
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0endi
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1endi
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0counti
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1counti
)
)
{
if
(
MI
.
getOpcode
(
)
==
RISCV
::
LOOP0setupi
||
MI
.
getOpcode
(
)
==
RISCV
::
LOOP1setupi
)
{
RISCV
::
Fixups
FixupKind
=
RISCV
::
fixup_pulpv2_loop_setupi
;
Fixups
.
push_back
(
MCFixup
::
create
(
0
,
MO
.
getExpr
(
)
,
MCFixupKind
(
FixupKind
)
,
MI
.
getLoc
(
)
)
)
;
}
else
{
RISCV
::
Fixups
FixupKind
=
RISCV
::
fixup_pulpv2_loop_setup
;
Fixups
.
push_back
(
MCFixup
::
create
(
0
,
MO
.
getExpr
(
)
,
MCFixupKind
(
FixupKind
)
,
MI
.
getLoc
(
)
)
)
;
}
++
MCNumFixups
;
return
0
;
}
llvm_unreachable
(
"Unhandled expression!"
)
;
return
0
;
}
</s>

getMachineOpValue - Return binary encoding of operand .


<s> static bool classof ( const RISCVMCExpr * ) { return true ; } </s>

Methods for support type inquiry through isa , cast , and dyn_cast :


<s> const RISCVMCExpr * RISCVMCExpr :: create ( const MCExpr * Expr , VariantKind Kind , MCContext & Ctx ) { return new ( Ctx ) RISCVMCExpr ( Expr , Kind ) ; } </s>


<s> bool RISCVMCExpr :: evaluateAsConstant ( int64_t & Res ) const { MCValue Value ; if ( Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO || Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_TPREL_HI || Kind == VK_RISCV_TPREL_LO || Kind == VK_RISCV_TPREL_ADD || Kind == VK_RISCV_TLS_GOT_HI || Kind == VK_RISCV_TLS_GD_HI || Kind == VK_RISCV_CALL || Kind == VK_RISCV_CALL_PLT ) return false ; if ( ! getSubExpr ( ) -> evaluateAsRelocatable ( Value , nullptr , nullptr ) ) return false ; if ( ! Value . isAbsolute ( ) ) return false ; Res = evaluateAsInt64 ( Value . getConstant ( ) ) ; return true ; } </s>

Evaluates the fixup as a constant value .

RI5CY RISCV RISCV RISCV RISCV RISCV RISCV RISCV RISCV RISCV RISCV RISCV


<s> MCFragment * findAssociatedFragment ( ) const override { return getSubExpr ( ) -> findAssociatedFragment ( ) ; } </s>

Find the `` associated section '' for this expression , which is currently defined as the absolute section for constants , or otherwise the section associated with the first defined symbol in the expression .


<s> VariantKind getKind ( ) const { return Kind ; } </s>


<s> const MCFixup * RISCVMCExpr :: getPCRelHiFixup ( const MCFragment * * DFOut ) const { MCValue AUIPCLoc ; if ( ! getSubExpr ( ) -> evaluateAsRelocatable ( AUIPCLoc , nullptr , nullptr ) ) return nullptr ; const MCSymbolRefExpr * AUIPCSRE = AUIPCLoc . getSymA ( ) ; if ( ! AUIPCSRE ) return nullptr ; const MCSymbol * AUIPCSymbol = & AUIPCSRE -> getSymbol ( ) ; const auto * DF = dyn_cast_or_null < MCDataFragment > ( AUIPCSymbol -> getFragment ( ) ) ; if ( ! DF ) return nullptr ; uint64_t Offset = AUIPCSymbol -> getOffset ( ) ; if ( DF -> getContents ( ) . size ( ) == Offset ) { DF = dyn_cast_or_null < MCDataFragment > ( DF -> getNextNode ( ) ) ; if ( ! DF ) return nullptr ; Offset = 0 ; } for ( const MCFixup & F : DF -> getFixups ( ) ) { if ( F . getOffset ( ) != Offset ) continue ; switch ( ( unsigned ) F . getKind ( ) ) { default : continue ; case RISCV :: fixup_riscv_got_hi20 : case RISCV :: fixup_riscv_tls_got_hi20 : case RISCV :: fixup_riscv_tls_gd_hi20 : case RISCV :: fixup_riscv_pcrel_hi20 : if ( DFOut ) * DFOut = DF ; return & F ; } } return nullptr ; } </s>

Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO points to , and optionally the fragment containing it .


<s> const MCExpr * getSubExpr ( ) const { return Expr ; } </s>

getSubExpr - Get the child of this expression .


<s>
StringRef
RISCVMCExpr
::
getVariantKindName
(
VariantKind
Kind
)
{
switch
(
Kind
)
{
default
:
llvm_unreachable
(
"Invalid ELF symbol kind"
)
;
case
VK_RISCV_LO
:
return
"lo"
;
case
VK_RISCV_HI
:
return
"hi"
;
case
VK_RISCV_PCREL_LO
:
return
"pcrel_lo"
;
case
VK_RISCV_PCREL_HI
:
return
"pcrel_hi"
;
case
VK_RISCV_GOT_HI
:
return
"got_pcrel_hi"
;
case
VK_RISCV_TPREL_LO
:
return
"tprel_lo"
;
case
VK_RISCV_TPREL_HI
:
return
"tprel_hi"
;
case
VK_RISCV_TPREL_ADD
:
return
"tprel_add"
;
case
VK_RISCV_TLS_GOT_HI
:
return
"tls_ie_pcrel_hi"
;
case
VK_RISCV_TLS_GD_HI
:
return
"tls_gd_pcrel_hi"
;
}
}
</s>

Convert the variant kind into an ELF-appropriate modifier ( e.g .


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { if ( isConditionalBranch ( Inst ) ) { int64_t Imm ; if ( Size == 2 ) Imm = Inst . getOperand ( 1 ) . getImm ( ) ; else Imm = Inst . getOperand ( 2 ) . getImm ( ) ; Target = Addr + Imm ; return true ; } if ( Inst . getOpcode ( ) == RISCV :: C_JAL || Inst . getOpcode ( ) == RISCV :: C_J ) { Target = Addr + Inst . getOperand ( 0 ) . getImm ( ) ; return true ; } if ( Inst . getOpcode ( ) == RISCV :: JAL ) { Target = Addr + Inst . getOperand ( 1 ) . getImm ( ) ; return true ; } return false ; } </s>

Given a branch instruction try to get the address the branch targets .


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

getPassName - Return a nice clean name for a pass .


"  Found lowered global address with one use: "

runOnMachineFunction - Emit the function body .


"Frame offsets outside of the signed 32-bit range not supported"

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


<s>
const
MCPhysReg
*
RISCVRegisterInfo
::
getCalleeSavedRegs
(
const
MachineFunction
*
MF
)
const
{
auto
&
Subtarget
=
MF
->
getSubtarget
<
RISCVSubtarget
>
(
)
;
if
(
MF
->
getFunction
(
)
.
getCallingConv
(
)
==
CallingConv
::
GHC
)
return
CSR_NoRegs_SaveList
;
if
(
MF
->
getFunction
(
)
.
hasFnAttribute
(
"interrupt"
)
)
{
if
(
Subtarget
.
hasStdExtD
(
)
)
return
CSR_XLEN_F64_Interrupt_SaveList
;
if
(
Subtarget
.
hasStdExtF
(
)
)
return
CSR_XLEN_F32_Interrupt_SaveList
;
return
CSR_Interrupt_SaveList
;
}
switch
(
Subtarget
.
getTargetABI
(
)
)
{
default
:
llvm_unreachable
(
"Unrecognized ABI"
)
;
case
RISCVABI
::
ABI_ILP32
:
case
RISCVABI
::
ABI_LP64
:
return
CSR_ILP32_LP64_SaveList
;
case
RISCVABI
::
ABI_ILP32F
:
case
RISCVABI
::
ABI_LP64F
:
return
CSR_ILP32F_LP64F_SaveList
;
case
RISCVABI
::
ABI_ILP32D
:
case
RISCVABI
::
ABI_LP64D
:
return
CSR_ILP32D_LP64D_SaveList
;
}
}
</s>


<s>
const
uint32_t
*
RISCVRegisterInfo
::
getCallPreservedMask
(
const
MachineFunction
&
MF
,
CallingConv
::
ID
CC
)
const
{
auto
&
Subtarget
=
MF
.
getSubtarget
<
RISCVSubtarget
>
(
)
;
if
(
CC
==
CallingConv
::
GHC
)
return
CSR_NoRegs_RegMask
;
switch
(
Subtarget
.
getTargetABI
(
)
)
{
default
:
llvm_unreachable
(
"Unrecognized ABI"
)
;
case
RISCVABI
::
ABI_ILP32
:
case
RISCVABI
::
ABI_LP64
:
return
CSR_ILP32_LP64_RegMask
;
case
RISCVABI
::
ABI_ILP32F
:
case
RISCVABI
::
ABI_LP64F
:
return
CSR_ILP32F_LP64F_RegMask
;
case
RISCVABI
::
ABI_ILP32D
:
case
RISCVABI
::
ABI_LP64D
:
return
CSR_ILP32D_LP64D_RegMask
;
}
}
</s>

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


<s> Register RISCVRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = getFrameLowering ( MF ) ; return TFI -> hasFP ( MF ) ? RISCV :: X8 : RISCV :: X2 ; } </s>


<s> const uint32_t * RISCVRegisterInfo :: getNoPreservedMask ( ) const { return CSR_NoRegs_RegMask ; } </s>

Return a register mask that clobbers everything .


<s> const TargetRegisterClass * getPointerRegClass ( const MachineFunction & MF , unsigned Kind = 0 ) const override { return & RISCV :: GPRRegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> BitVector RISCVRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const RISCVFrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; const auto * RVFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; for ( size_t Reg = 0 ; Reg < getNumRegs ( ) ; Reg ++ ) { if ( MF . getSubtarget < RISCVSubtarget > ( ) . isRegisterReservedByUser ( Reg ) ) markSuperRegs ( Reserved , Reg ) ; } markSuperRegs ( Reserved , RISCV :: X0 ) ; markSuperRegs ( Reserved , RISCV :: X2 ) ; markSuperRegs ( Reserved , RISCV :: X3 ) ; markSuperRegs ( Reserved , RISCV :: X4 ) ; if ( TFI -> hasFP ( MF ) ) markSuperRegs ( Reserved , RISCV :: X8 ) ; if ( TFI -> hasBP ( MF ) ) markSuperRegs ( Reserved , RISCVABI :: getBPReg ( ) ) ; markSuperRegs ( Reserved , RISCV :: VL ) ; markSuperRegs ( Reserved , RISCV :: VTYPE ) ; markSuperRegs ( Reserved , RISCV :: VXSAT ) ; markSuperRegs ( Reserved , RISCV :: VXRM ) ; for ( unsigned n = 0 ; n != 8 ; ++ n ) { if ( RVFI -> getUsedSSR ( ) & ( 1 << n ) ) markSuperRegs ( Reserved , RISCV :: F0_D + n ) ; } assert ( checkAllSuperRegsMarked ( Reserved ) ) ; 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 .


<s> bool RISCVRegisterInfo :: hasReservedSpillSlot ( const MachineFunction & MF , Register Reg , int & FrameIdx ) const { const auto * RVFI = MF . getInfo < RISCVMachineFunctionInfo > ( ) ; if ( ! RVFI -> useSaveRestoreLibCalls ( MF ) ) return false ; auto FII = FixedCSRFIMap . find ( Reg ) ; if ( FII == FixedCSRFIMap . end ( ) ) return false ; FrameIdx = FII -> second ; return true ; } </s>

Return true if target has reserved a spill slot in the stack frame of the given function for the specified register .


<s> bool RISCVRegisterInfo :: isAsmClobberable ( const MachineFunction & MF , MCRegister PhysReg ) const { return ! MF . getSubtarget < RISCVSubtarget > ( ) . isRegisterReservedByUser ( PhysReg ) ; } </s>

Returns false if we ca n't guarantee that Physreg , specified as an IR asm clobber constraint , will be preserved across the statement .


<s> bool RISCVRegisterInfo :: isConstantPhysReg ( MCRegister PhysReg ) const { return PhysReg == RISCV :: X0 ; } </s>

Returns true if PhysReg is unallocatable and constant throughout the function .


<s> bool requiresFrameIndexScavenging ( const MachineFunction & MF ) const override { return true ; } </s>

Returns true if the target requires post PEI scavenging of registers for materializing frame index constants .


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

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


<s> bool enableMachineScheduler ( ) const override { return true ; } </s>

Enable the MachineScheduler pass for all X86 subtargets .


<s> const CallLowering * RISCVSubtarget :: getCallLowering ( ) const { return CallLoweringInfo . get ( ) ; } </s>


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


<s> const LegalizerInfo * RISCVSubtarget :: getLegalizerInfo ( ) const { return Legalizer . get ( ) ; } </s>

Expose LegalizerInfo so the clients can re-use .


<s> const RegisterBankInfo * RISCVSubtarget :: getRegBankInfo ( ) const { return RegBankInfo . get ( ) ; } </s>

If the information for the register banks is available , return it .


<s> const RISCVRegisterInfo * getRegisterInfo ( ) const override { return & RegInfo ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> RISCVSubtarget & RISCVSubtarget :: initializeSubtargetDependencies ( const Triple & TT , StringRef CPU , StringRef TuneCPU , StringRef FS , StringRef ABIName ) { bool Is64Bit = TT . isArch64Bit ( ) ; std :: string CPUName = std :: string ( CPU ) ; std :: string TuneCPUName = std :: string ( TuneCPU ) ; if ( CPUName . empty ( ) ) CPUName = Is64Bit ? "generic-rv64" : "generic-rv32" ; if ( TuneCPUName . empty ( ) ) TuneCPUName = CPUName ; ParseSubtargetFeatures ( CPUName , TuneCPUName , FS ) ; if ( Is64Bit ) { XLenVT = MVT :: i64 ; XLen = 64 ; } TargetABI = RISCVABI :: computeTargetABI ( TT , getFeatureBits ( ) , ABIName ) ; RISCVFeatures :: validate ( TT , getFeatureBits ( ) ) ; if ( TT . getVendor ( ) == Triple :: HERO ) { IsPULP = true ; } return * this ; } </s>

initializeSubtargetDependencies - Initializes using a CPU , a TuneCPU , and feature string so that we can use initializer lists for subtarget initialization .


<s> bool RISCVPassConfig :: addGlobalInstructionSelect ( ) { addPass ( new InstructionSelect ( ) ) ; return false ; } </s>

This method should install a ( global ) instruction selector pass , which converts possibly generic instructions to fully target-specific instructions , thereby constraining all generic virtual registers to register classes .


<s> bool RISCVPassConfig :: addInstSelector ( ) { addPass ( createRISCVISelDag ( getRISCVTargetMachine ( ) ) ) ; return false ; } </s>

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


<s> void RISCVPassConfig :: addIRPasses ( ) { addPass ( createAtomicExpandPass ( ) ) ; TargetPassConfig :: addIRPasses ( ) ; } </s>

Add common target configurable passes that perform LLVM IR to IR transforms following machine independent optimization .


<s> bool RISCVPassConfig :: addIRTranslator ( ) { addPass ( new IRTranslator ( getOptLevel ( ) ) ) ; return false ; } </s>

This method should install an IR translator pass , which converts from LLVM code to machine instructions with possibly generic opcodes .


<s> bool RISCVPassConfig :: addLegalizeMachineIR ( ) { addPass ( new Legalizer ( ) ) ; return false ; } </s>

This method should install a legalize pass , which converts the instruction sequence into one that can be selected by the target .


<s> void RISCVPassConfig :: addPreEmitPass ( ) { addPass ( & BranchRelaxationPassID ) ; } </s>

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


<s> void RISCVPassConfig :: addPreEmitPass2 ( ) { addPass ( createRISCVExpandPseudoPass ( ) ) ; addPass ( createPULPFixupHwLoops ( ) ) ; addPass ( createRISCVExpandAtomicPseudoPass ( ) ) ; } </s>

Targets may add passes immediately before machine code is emitted in this callback .


<s> void RISCVPassConfig :: addPreRegAlloc ( ) { addPass ( createRISCVExpandSDMAPass ( ) ) ; addPass ( createRISCVExpandSSRPass ( ) ) ; addPass ( createSNITCHFrepLoopsPass ( ) ) ; if ( TM -> getOptLevel ( ) != CodeGenOpt :: None ) { addPass ( createRISCVMergeBaseOffsetOptPass ( ) ) ; addPass ( createRISCVCleanupVSETVLIPass ( ) ) ; addPass ( createPULPHardwareLoops ( ) ) ; } } </s>

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


<s> void RISCVPassConfig :: addPreSched2 ( ) { } </s>

This method may be implemented by targets that want to run passes after prolog-epilog insertion and before the second instruction scheduling pass .


<s> bool RISCVPassConfig :: addRegBankSelect ( ) { addPass ( new RegBankSelect ( ) ) ; return false ; } </s>

This method should install a register bank selector pass , which assigns register banks to virtual registers without a register class or register banks .


<s> TargetPassConfig * RISCVTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new RISCVPassConfig ( * 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 .


"-target-abi option != target-abi module flag"

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


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

Get a TargetTransformInfo implementation for the target .


<s> bool RISCVTargetMachine :: isNoopAddrSpaceCast ( unsigned SrcAS , unsigned DstAS ) const { return true ; } </s>

Returns true if a cast between SrcAS and DestAS is a noop .


<s> void RISCVELFTargetObjectFile :: getModuleMetadata ( Module & M ) { SmallVector < Module :: ModuleFlagEntry , 8 > ModuleFlags ; M . getModuleFlagsMetadata ( ModuleFlags ) ; for ( const auto & MFE : ModuleFlags ) { StringRef Key = MFE . Key -> getString ( ) ; if ( Key == "SmallDataLimit" ) { SSThreshold = mdconst :: extract < ConstantInt > ( MFE . Val ) -> getZExtValue ( ) ; break ; } } } </s>

Get the module-level metadata that the platform cares about .


<s> MCSection * RISCVELFTargetObjectFile :: getSectionForConstant ( const DataLayout & DL , SectionKind Kind , const Constant * C , Align & Alignment ) const { if ( isConstantInSmallSection ( DL , C ) ) return SmallDataSection ; return TargetLoweringObjectFileELF :: getSectionForConstant ( DL , Kind , C , Alignment ) ; } </s>

Given a constant with the SectionKind , return a section that it should be placed in .


<s> void RISCVELFTargetObjectFile :: Initialize ( MCContext & Ctx , const TargetMachine & TM ) { TargetLoweringObjectFileELF :: Initialize ( Ctx , TM ) ; SmallDataSection = getContext ( ) . getELFSection ( ".sdata" , ELF :: SHT_PROGBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; SmallBSSSection = getContext ( ) . getELFSection ( ".sbss" , ELF :: SHT_NOBITS , ELF :: SHF_WRITE | ELF :: SHF_ALLOC ) ; } </s>

This method must be called before any actual lowering is done .


<s> bool RISCVELFTargetObjectFile :: isConstantInSmallSection ( const DataLayout & DL , const Constant * CN ) const { return isInSmallSection ( DL . getTypeAllocSize ( CN -> getType ( ) ) ) ; } </s>

Return true if this constant should be placed into small data section .


<s> bool RISCVELFTargetObjectFile :: isGlobalInSmallSection ( const GlobalObject * GO , const TargetMachine & TM ) const { const GlobalVariable * GVA = dyn_cast < GlobalVariable > ( GO ) ; if ( ! GVA ) return false ; if ( GVA -> hasSection ( ) ) { StringRef Section = GVA -> getSection ( ) ; if ( Section == ".sdata" || Section == ".sbss" ) return true ; return false ; } if ( ( ( GVA -> hasExternalLinkage ( ) && GVA -> isDeclaration ( ) ) || GVA -> hasCommonLinkage ( ) ) ) return false ; Type * Ty = GVA -> getValueType ( ) ; if ( ! Ty -> isSized ( ) ) return false ; return isInSmallSection ( GVA -> getParent ( ) -> getDataLayout ( ) . getTypeAllocSize ( Ty ) ) ; } </s>

Return true if this global address should be placed into small data/bss section .