Commit 03ffa585 by Jim Stichnoth

Subzero: Legalize FP constants directly into memory operands.

Previously, the legalize() function would always force a floating point constant into an xmm register before it could be used in an instruction. This uses an extra register unnecessarily when the instruction allows a memory operand for that operand. We improve this by lowering the FP constant operand to an OperandX8632Mem that wraps a ConstantRelocatable representing the label for the constant pool entry, e.g. [.L$float$0]. (This may end up being copied into an xmm register if the instruction doesn't allow a memory operand for that operand.) BUG= https://code.google.com/p/nativeclient/issues/detail?id=4095 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/1163943005
parent 2f7f2b7e
...@@ -4590,6 +4590,7 @@ Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) { ...@@ -4590,6 +4590,7 @@ Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) {
Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed,
int32_t RegNum) { int32_t RegNum) {
Type Ty = From->getType();
// Assert that a physical register is allowed. To date, all calls // Assert that a physical register is allowed. To date, all calls
// to legalize() allow a physical register. If a physical register // to legalize() allow a physical register. If a physical register
// needs to be explicitly disallowed, then new code will need to be // needs to be explicitly disallowed, then new code will need to be
...@@ -4614,9 +4615,9 @@ Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, ...@@ -4614,9 +4615,9 @@ Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed,
RegIndex = legalizeToVar(Index); RegIndex = legalizeToVar(Index);
} }
if (Base != RegBase || Index != RegIndex) { if (Base != RegBase || Index != RegIndex) {
From = OperandX8632Mem::create( From =
Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
Mem->getShift(), Mem->getSegmentRegister()); Mem->getShift(), Mem->getSegmentRegister());
} }
if (!(Allowed & Legal_Mem)) { if (!(Allowed & Legal_Mem)) {
...@@ -4637,17 +4638,27 @@ Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, ...@@ -4637,17 +4638,27 @@ Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed,
// overestimated. If the constant being lowered is a 64 bit value, // overestimated. If the constant being lowered is a 64 bit value,
// then the result should be split and the lo and hi components will // then the result should be split and the lo and hi components will
// need to go in uninitialized registers. // need to go in uninitialized registers.
if (isVectorType(From->getType())) if (isVectorType(Ty))
return makeVectorOfZeros(From->getType(), RegNum); return makeVectorOfZeros(Ty, RegNum);
From = Ctx->getConstantZero(From->getType()); From = Ctx->getConstantZero(Ty);
} }
// There should be no constants of vector type (other than undef). // There should be no constants of vector type (other than undef).
assert(!isVectorType(From->getType())); assert(!isVectorType(Ty));
// Convert a scalar floating point constant into an explicit
// memory operand.
if (isScalarFloatingType(Ty)) {
Variable *Base = nullptr;
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
From = OperandX8632Mem::create(Func, Ty, Base, Offset);
}
bool NeedsReg = false; bool NeedsReg = false;
if (!(Allowed & Legal_Imm)) if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
// Immediate specifically not allowed // Immediate specifically not allowed
NeedsReg = true; NeedsReg = true;
if (!(Allowed & Legal_Mem) && isScalarFloatingType(From->getType())) if (!(Allowed & Legal_Mem) && isScalarFloatingType(Ty))
// On x86, FP constants are lowered to mem operands. // On x86, FP constants are lowered to mem operands.
NeedsReg = true; NeedsReg = true;
if (NeedsReg) { if (NeedsReg) {
......
...@@ -10,7 +10,6 @@ entry: ...@@ -10,7 +10,6 @@ entry:
} }
; CHECK-LABEL: cast_f2i ; CHECK-LABEL: cast_f2i
; CHECK: mov eax ; CHECK: mov eax
; CHECK: ret
define internal float @cast_i2f(i32 %i) { define internal float @cast_i2f(i32 %i) {
entry: entry:
...@@ -19,7 +18,6 @@ entry: ...@@ -19,7 +18,6 @@ entry:
} }
; CHECK-LABEL: cast_i2f ; CHECK-LABEL: cast_i2f
; CHECK: fld DWORD PTR ; CHECK: fld DWORD PTR
; CHECK: ret
define internal i64 @cast_d2ll(double %d) { define internal i64 @cast_d2ll(double %d) {
entry: entry:
...@@ -28,7 +26,6 @@ entry: ...@@ -28,7 +26,6 @@ entry:
} }
; CHECK-LABEL: cast_d2ll ; CHECK-LABEL: cast_d2ll
; CHECK: mov edx ; CHECK: mov edx
; CHECK: ret
define internal i64 @cast_d2ll_const() { define internal i64 @cast_d2ll_const() {
entry: entry:
...@@ -36,9 +33,8 @@ entry: ...@@ -36,9 +33,8 @@ entry:
ret i64 %v0 ret i64 %v0
} }
; CHECK-LABEL: cast_d2ll_const ; CHECK-LABEL: cast_d2ll_const
; CHECK: movsd xmm{{.*}},QWORD PTR ; CHECK: mov e{{..}},DWORD PTR ds:0x0 {{.*}} .L$double$0
; CHECK: mov edx ; CHECK: mov e{{..}},DWORD PTR ds:0x4 {{.*}} .L$double$0
; CHECK: ret
define internal double @cast_ll2d(i64 %ll) { define internal double @cast_ll2d(i64 %ll) {
entry: entry:
...@@ -47,7 +43,6 @@ entry: ...@@ -47,7 +43,6 @@ entry:
} }
; CHECK-LABEL: cast_ll2d ; CHECK-LABEL: cast_ll2d
; CHECK: fld QWORD PTR ; CHECK: fld QWORD PTR
; CHECK: ret
define internal double @cast_ll2d_const() { define internal double @cast_ll2d_const() {
entry: entry:
...@@ -58,4 +53,3 @@ entry: ...@@ -58,4 +53,3 @@ entry:
; CHECK: mov {{.*}},0x73ce2ff2 ; CHECK: mov {{.*}},0x73ce2ff2
; CHECK: mov {{.*}},0xb3a ; CHECK: mov {{.*}},0xb3a
; CHECK: fld QWORD PTR ; CHECK: fld QWORD PTR
; CHECK: ret
...@@ -182,7 +182,7 @@ entry: ...@@ -182,7 +182,7 @@ entry:
%val = insertelement <4 x float> %arg, float undef, i32 0 %val = insertelement <4 x float> %arg, float undef, i32 0
ret <4 x float> %val ret <4 x float> %val
; CHECK-LABEL: vector_insertelement_arg2 ; CHECK-LABEL: vector_insertelement_arg2
; CHECK: movss {{.*}},DWORD PTR {{.*}} .L$float$0 ; CHECK: {{movss|insertps}} {{.*}},DWORD PTR {{.*}} .L$float$0
} }
define float @vector_extractelement_v4f32_index_0() { define float @vector_extractelement_v4f32_index_0() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment