Skip to content

Commit

Permalink
[llvm][LoongArch] Support per-global code model attribute for LoongAr…
Browse files Browse the repository at this point in the history
…ch (llvm#72079)

This patch gets the code model from global variable attribute if it has,
otherwise the target's will be used.

---------

Signed-off-by: WANG Rui <wangrui@loongson.cn>
  • Loading branch information
heiher authored and justinfargnoli committed Jan 28, 2024
1 parent 0b86441 commit 903ff93
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
22 changes: 17 additions & 5 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,12 +762,13 @@ static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,

template <class NodeTy>
SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
CodeModel::Model M,
bool IsLocal) const {
SDLoc DL(N);
EVT Ty = getPointerTy(DAG.getDataLayout());
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);

switch (DAG.getTarget().getCodeModel()) {
switch (M) {
default:
report_fatal_error("Unsupported code model");

Expand Down Expand Up @@ -808,24 +809,35 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,

SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op,
SelectionDAG &DAG) const {
return getAddr(cast<BlockAddressSDNode>(Op), DAG);
return getAddr(cast<BlockAddressSDNode>(Op), DAG,
DAG.getTarget().getCodeModel());
}

SDValue LoongArchTargetLowering::lowerJumpTable(SDValue Op,
SelectionDAG &DAG) const {
return getAddr(cast<JumpTableSDNode>(Op), DAG);
return getAddr(cast<JumpTableSDNode>(Op), DAG,
DAG.getTarget().getCodeModel());
}

SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op,
SelectionDAG &DAG) const {
return getAddr(cast<ConstantPoolSDNode>(Op), DAG);
return getAddr(cast<ConstantPoolSDNode>(Op), DAG,
DAG.getTarget().getCodeModel());
}

SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
SelectionDAG &DAG) const {
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
assert(N->getOffset() == 0 && "unexpected offset in global node");
return getAddr(N, DAG, N->getGlobal()->isDSOLocal());
auto CM = DAG.getTarget().getCodeModel();
const GlobalValue *GV = N->getGlobal();

if (GV->isDSOLocal() && isa<GlobalVariable>(GV)) {
if (auto GCM = dyn_cast<GlobalVariable>(GV)->getCodeModel())
CM = *GCM;
}

return getAddr(N, DAG, CM, GV->isDSOLocal());
}

SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ class LoongArchTargetLowering : public TargetLowering {
LoongArchCCAssignFn Fn) const;

template <class NodeTy>
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
bool IsLocal = true) const;
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
unsigned Opc, bool Large = false) const;
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
Expand Down
44 changes: 44 additions & 0 deletions llvm/test/CodeGen/LoongArch/global-variable-code-model.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s

@a= external dso_local global i32, code_model "small", align 4

define dso_local signext i32 @local_small() #0 {
; CHECK-LABEL: local_small:
; CHECK: # %bb.0:
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(a)
; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(a)
; CHECK-NEXT: ld.w $a0, $a0, 0
; CHECK-NEXT: ret
%1 = load i32, ptr @a, align 4
ret i32 %1
}

@b= external dso_local global i32, code_model "large", align 4

define dso_local signext i32 @local_large() #0 {
; CHECK-LABEL: local_large:
; CHECK: # %bb.0:
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(b)
; CHECK-NEXT: addi.d $t8, $zero, %pc_lo12(b)
; CHECK-NEXT: lu32i.d $t8, %pc64_lo20(b)
; CHECK-NEXT: lu52i.d $t8, $t8, %pc64_hi12(b)
; CHECK-NEXT: add.d $a0, $t8, $a0
; CHECK-NEXT: ld.w $a0, $a0, 0
; CHECK-NEXT: ret
%1 = load i32, ptr @b, align 4
ret i32 %1
}

@c= external global i32, code_model "large", align 4

define dso_local signext i32 @non_local_large() #0 {
; CHECK-LABEL: non_local_large:
; CHECK: # %bb.0:
; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(c)
; CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(c)
; CHECK-NEXT: ld.w $a0, $a0, 0
; CHECK-NEXT: ret
%1 = load i32, ptr @c, align 4
ret i32 %1
}

0 comments on commit 903ff93

Please sign in to comment.