Skip to content

Commit 44668ae

Browse files
committedApr 1, 2019
[RISCV] Attach VK_RISCV_CALL to symbols upon creation
This patch replaces the addition of VK_RISCV_CALL in RISCVMCCodeEmitter by creating the RISCVMCExpr when tail/call are parsed, or in the codegen case when the callee symbols are created. This required adding a new CallSymbol operand to allow only adding VK_RISCV_CALL to tail/call instructions. This patch will allow further expansion of parsing and codegen to easily include PLT symbols which must generate the R_RISCV_CALL_PLT relocation. Differential Revision: https://reviews.llvm.org/D55560 Patch by Lewis Revill. llvm-svn: 357396
1 parent 9142b8e commit 44668ae

File tree

6 files changed

+57
-9
lines changed

6 files changed

+57
-9
lines changed
 

‎llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
113113
OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
114114
OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
115115
OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
116+
OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
116117
OperandMatchResultTy parseJALOffset(OperandVector &Operands);
117118

118119
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
@@ -283,6 +284,16 @@ struct RISCVOperand : public MCParsedAsmOperand {
283284
VK == RISCVMCExpr::VK_RISCV_None;
284285
}
285286

287+
bool isCallSymbol() const {
288+
int64_t Imm;
289+
RISCVMCExpr::VariantKind VK;
290+
// Must be of 'immediate' type but not a constant.
291+
if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
292+
return false;
293+
return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
294+
VK == RISCVMCExpr::VK_RISCV_CALL;
295+
}
296+
286297
bool isCSRSystemRegister() const { return isSystemRegister(); }
287298

288299
/// Return true if the operand is a valid for the fence instruction e.g.
@@ -904,6 +915,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
904915
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
905916
return Error(ErrorLoc, "operand must be a bare symbol name");
906917
}
918+
case Match_InvalidCallSymbol: {
919+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
920+
return Error(ErrorLoc, "operand must be a bare symbol name");
921+
}
907922
}
908923

909924
llvm_unreachable("Unknown match type detected!");
@@ -1142,6 +1157,25 @@ OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
11421157
return MatchOperand_Success;
11431158
}
11441159

1160+
OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1161+
SMLoc S = getLoc();
1162+
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1163+
const MCExpr *Res;
1164+
1165+
if (getLexer().getKind() != AsmToken::Identifier)
1166+
return MatchOperand_NoMatch;
1167+
1168+
StringRef Identifier;
1169+
if (getParser().parseIdentifier(Identifier))
1170+
return MatchOperand_ParseFail;
1171+
1172+
MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1173+
Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1174+
Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1175+
Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1176+
return MatchOperand_Success;
1177+
}
1178+
11451179
OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
11461180
// Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
11471181
// both being acceptable forms. When parsing `jal ra, foo` this function

‎llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,7 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS,
101101

102102
assert(Func.isExpr() && "Expected expression");
103103

104-
const MCExpr *Expr = Func.getExpr();
105-
106-
// Create function call expression CallExpr for AUIPC.
107-
const MCExpr *CallExpr =
108-
RISCVMCExpr::create(Expr, RISCVMCExpr::VK_RISCV_CALL, Ctx);
104+
const MCExpr *CallExpr = Func.getExpr();
109105

110106
// Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
111107
TmpInst = MCInstBuilder(RISCV::AUIPC)

‎llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,9 +1811,11 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
18111811
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
18121812
// split it and then direct call can be matched by PseudoCALL.
18131813
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
1814-
Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, 0);
1814+
Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0,
1815+
RISCVII::MO_CALL);
18151816
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1816-
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, 0);
1817+
Callee =
1818+
DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, RISCVII::MO_CALL);
18171819
}
18181820

18191821
// The first call operand is the chain and the second is the target address.

‎llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,18 @@ def bare_symbol : Operand<XLenVT> {
190190
let ParserMatchClass = BareSymbol;
191191
}
192192

193+
def CallSymbol : AsmOperandClass {
194+
let Name = "CallSymbol";
195+
let RenderMethod = "addImmOperands";
196+
let DiagnosticType = "InvalidCallSymbol";
197+
let ParserMethod = "parseCallSymbol";
198+
}
199+
200+
// A bare symbol used in call/tail only.
201+
def call_symbol : Operand<XLenVT> {
202+
let ParserMatchClass = CallSymbol;
203+
}
204+
193205
def CSRSystemRegister : AsmOperandClass {
194206
let Name = "CSRSystemRegister";
195207
let ParserMethod = "parseCSRSystemRegister";
@@ -844,7 +856,7 @@ def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
844856
// Define AsmString to print "call" when compile with -S flag.
845857
// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
846858
let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
847-
def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
859+
def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func),
848860
[(riscv_call tglobaladdr:$func)]> {
849861
let AsmString = "call\t$func";
850862
}
@@ -869,7 +881,7 @@ def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_flag)]>,
869881
// Define AsmString to print "tail" when compile with -S flag.
870882
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
871883
isCodeGenOnly = 0 in
872-
def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst), []> {
884+
def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), []> {
873885
let AsmString = "tail\t$dst";
874886
}
875887

‎llvm/lib/Target/RISCV/RISCVMCInstLower.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
3636
case RISCVII::MO_None:
3737
Kind = RISCVMCExpr::VK_RISCV_None;
3838
break;
39+
case RISCVII::MO_CALL:
40+
Kind = RISCVMCExpr::VK_RISCV_CALL;
41+
break;
3942
case RISCVII::MO_LO:
4043
Kind = RISCVMCExpr::VK_RISCV_LO;
4144
break;

‎llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum {
4848

4949
enum {
5050
MO_None,
51+
MO_CALL,
5152
MO_LO,
5253
MO_HI,
5354
MO_PCREL_LO,

0 commit comments

Comments
 (0)
Please sign in to comment.