Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
3b2883b0
R
runtime
项目概览
dotNET Platform
/
runtime
11 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
3b2883b0
编写于
6月 16, 2022
作者:
W
Will Smith
提交者:
GitHub
6月 16, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ARM64 - Optimize `i % 2` (#70599)
上级
3b1a36e5
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
81 addition
and
41 deletion
+81
-41
src/coreclr/jit/codegenarm64.cpp
src/coreclr/jit/codegenarm64.cpp
+21
-10
src/coreclr/jit/codegenarmarch.cpp
src/coreclr/jit/codegenarmarch.cpp
+1
-0
src/coreclr/jit/gentree.cpp
src/coreclr/jit/gentree.cpp
+4
-1
src/coreclr/jit/gtlist.h
src/coreclr/jit/gtlist.h
+1
-0
src/coreclr/jit/lowerarmarch.cpp
src/coreclr/jit/lowerarmarch.cpp
+54
-30
未找到文件。
src/coreclr/jit/codegenarm64.cpp
浏览文件 @
3b2883b0
...
...
@@ -10282,30 +10282,41 @@ void CodeGen::genCodeForAddEx(GenTreeOp* tree)
//
void
CodeGen
::
genCodeForCond
(
GenTreeOp
*
tree
)
{
assert
(
tree
->
OperIs
(
GT_CSNEG_MI
));
assert
(
tree
->
OperIs
(
GT_CSNEG_MI
,
GT_CNEG_LT
));
assert
(
!
(
tree
->
gtFlags
&
GTF_SET_FLAGS
));
genConsumeOperands
(
tree
);
instruction
ins
;
insCond
cond
;
switch
(
tree
->
OperGet
())
{
case
GT_CSNEG_MI
:
{
ins
=
INS_csneg
;
cond
=
INS_COND_MI
;
instruction
ins
=
INS_csneg
;
insCond
cond
=
INS_COND_MI
;
regNumber
dstReg
=
tree
->
GetRegNum
();
regNumber
op1Reg
=
tree
->
gtGetOp1
()
->
GetRegNum
();
regNumber
op2Reg
=
tree
->
gtGetOp2
()
->
GetRegNum
();
GetEmitter
()
->
emitIns_R_R_R_COND
(
ins
,
emitActualTypeSize
(
tree
),
dstReg
,
op1Reg
,
op2Reg
,
cond
);
break
;
}
default:
unreached
();
}
case
GT_CNEG_LT
:
{
instruction
ins
=
INS_cneg
;
insCond
cond
=
INS_COND_LT
;
regNumber
dstReg
=
tree
->
GetRegNum
();
regNumber
op1Reg
=
tree
->
gtGetOp1
()
->
GetRegNum
();
regNumber
op2Reg
=
tree
->
gtGetOp2
()
->
GetRegNum
();
GetEmitter
()
->
emitIns_R_R_R_COND
(
ins
,
emitActualTypeSize
(
tree
),
dstReg
,
op1Reg
,
op2Reg
,
cond
);
GetEmitter
()
->
emitIns_R_R_COND
(
ins
,
emitActualTypeSize
(
tree
),
dstReg
,
op1Reg
,
cond
);
break
;
}
default:
unreached
();
}
genProduceReg
(
tree
);
}
...
...
src/coreclr/jit/codegenarmarch.cpp
浏览文件 @
3b2883b0
...
...
@@ -324,6 +324,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
break
;
case
GT_CSNEG_MI
:
case
GT_CNEG_LT
:
genCodeForCond
(
treeNode
->
AsOp
());
break
;
#endif // TARGET_ARM64
...
...
src/coreclr/jit/gentree.cpp
浏览文件 @
3b2883b0
...
...
@@ -9161,7 +9161,10 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
m_state = -1;
return;
// Standard unary operators
// Standard unary operators
#ifdef TARGET_ARM64
case GT_CNEG_LT:
#endif // TARGET_ARM64
case GT_STORE_LCL_VAR:
case GT_STORE_LCL_FLD:
case GT_NOT:
...
...
src/coreclr/jit/gtlist.h
浏览文件 @
3b2883b0
...
...
@@ -219,6 +219,7 @@ GTNODE(AND_NOT , GenTreeOp ,0,GTK_BINOP|DBK_NOTHIR)
GTNODE
(
ADDEX
,
GenTreeOp
,
0
,
GTK_BINOP
|
DBK_NOTHIR
)
// Add with sign/zero extension.
GTNODE
(
BFIZ
,
GenTreeOp
,
0
,
GTK_BINOP
|
DBK_NOTHIR
)
// Bitfield Insert in Zero.
GTNODE
(
CSNEG_MI
,
GenTreeOp
,
0
,
GTK_BINOP
|
DBK_NOTHIR
)
// Conditional select, negate, minus result
GTNODE
(
CNEG_LT
,
GenTreeOp
,
0
,
GTK_UNOP
|
DBK_NOTHIR
)
// Conditional, negate, signed less than result
#endif
//-----------------------------------------------------------------------------
...
...
src/coreclr/jit/lowerarmarch.cpp
浏览文件 @
3b2883b0
...
...
@@ -104,6 +104,7 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const
case
GT_LE
:
case
GT_GE
:
case
GT_GT
:
case
GT_CMP
:
case
GT_BOUNDS_CHECK
:
return
emitter
::
emitIns_valid_imm_for_cmp
(
immVal
,
size
);
case
GT_AND
:
...
...
@@ -699,19 +700,7 @@ void Lowering::LowerRotate(GenTree* tree)
// Arguments:
// tree - the node to lower
//
// Return Value:
// A new tree node if it changed.
//
// Notes:
// {expr} % {cns}
// Logically turns into:
// let a = {expr}
// if a > 0 then (a & ({cns} - 1)) else -(-a & ({cns} - 1))
// which then turns into:
// and reg1, reg0, #({cns} - 1)
// negs reg0, reg0
// and reg0, reg0, #({cns} - 1)
// csneg reg0, reg1, reg0, mi
// TODO: We could do this optimization in morph but we do not have
// a conditional select op in HIR. At some point, we may
// introduce such an op.
...
...
@@ -722,12 +711,15 @@ void Lowering::LowerModPow2(GenTree* node)
GenTree
*
dividend
=
mod
->
gtGetOp1
();
GenTree
*
divisor
=
mod
->
gtGetOp2
();
JITDUMP
(
"Lower: optimize X MOD POW2"
);
assert
(
divisor
->
IsIntegralConstPow2
());
const
var_types
type
=
mod
->
TypeGet
();
assert
((
type
==
TYP_INT
)
||
(
type
==
TYP_LONG
));
ssize_t
cnsValue
=
static_cast
<
ssize_t
>
(
divisor
->
AsIntConCommon
()
->
IntegralValue
())
-
1
;
ssize_t
divisorCnsValue
=
static_cast
<
ssize_t
>
(
divisor
->
AsIntConCommon
()
->
IntegralValue
());
ssize_t
divisorCnsValueMinusOne
=
divisorCnsValue
-
1
;
BlockRange
().
Remove
(
divisor
);
...
...
@@ -739,18 +731,52 @@ void Lowering::LowerModPow2(GenTree* node)
GenTree
*
dividend2
=
comp
->
gtClone
(
dividend
);
BlockRange
().
InsertAfter
(
dividend
,
dividend2
);
GenTreeIntCon
*
cns
=
comp
->
gtNewIconNode
(
cnsValu
e
,
type
);
GenTreeIntCon
*
cns
=
comp
->
gtNewIconNode
(
divisorCnsValueMinusOn
e
,
type
);
BlockRange
().
InsertAfter
(
dividend2
,
cns
);
GenTree
*
const
trueExpr
=
comp
->
gtNewOperNode
(
GT_AND
,
type
,
dividend
,
cns
);
BlockRange
().
InsertAfter
(
cns
,
trueExpr
);
LowerNode
(
trueExpr
);
if
(
divisorCnsValue
==
2
)
{
// {expr} % 2
// Logically turns into:
// let a = {expr}
// if a < 0 then -(a & 1) else (a & 1)
// which then turns into:
// and reg1, reg0, #1
// cmp reg0, #0
// cneg reg0, reg1, lt
GenTreeIntCon
*
cnsZero
=
comp
->
gtNewIconNode
(
0
,
type
);
BlockRange
().
InsertAfter
(
trueExpr
,
cnsZero
);
GenTree
*
const
cmp
=
comp
->
gtNewOperNode
(
GT_CMP
,
type
,
dividend2
,
cnsZero
);
cmp
->
gtFlags
|=
GTF_SET_FLAGS
;
BlockRange
().
InsertAfter
(
cnsZero
,
cmp
);
LowerNode
(
cmp
);
mod
->
ChangeOper
(
GT_CNEG_LT
);
mod
->
gtOp1
=
trueExpr
;
}
else
{
// {expr} % {cns}
// Logically turns into:
// let a = {expr}
// if a > 0 then (a & ({cns} - 1)) else -(-a & ({cns} - 1))
// which then turns into:
// and reg1, reg0, #({cns} - 1)
// negs reg0, reg0
// and reg0, reg0, #({cns} - 1)
// csneg reg0, reg1, reg0, mi
GenTree
*
const
neg
=
comp
->
gtNewOperNode
(
GT_NEG
,
type
,
dividend2
);
neg
->
gtFlags
|=
GTF_SET_FLAGS
;
BlockRange
().
InsertAfter
(
trueExpr
,
neg
);
GenTreeIntCon
*
cns2
=
comp
->
gtNewIconNode
(
cnsValu
e
,
type
);
GenTreeIntCon
*
cns2
=
comp
->
gtNewIconNode
(
divisorCnsValueMinusOn
e
,
type
);
BlockRange
().
InsertAfter
(
neg
,
cns2
);
GenTree
*
const
falseExpr
=
comp
->
gtNewOperNode
(
GT_AND
,
type
,
neg
,
cns2
);
...
...
@@ -760,9 +786,7 @@ void Lowering::LowerModPow2(GenTree* node)
mod
->
ChangeOper
(
GT_CSNEG_MI
);
mod
->
gtOp1
=
trueExpr
;
mod
->
gtOp2
=
falseExpr
;
JITDUMP
(
"Lower: optimize X MOD POW2"
);
DISPNODE
(
mod
);
}
ContainCheckNode
(
mod
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录