Commit 53483691 by Jan Voung

Factor out prelowerPhi for 32-bit targets. Disable adv phi lowering for ARM.

This way, prelowerPhi can be shared between 32-bit targets (split 64-bit values into 32-bit ones, and legalize undef). Suggestions from template experts on how to share prelowerPhi welcome. I'm not particularly happy with the first pass in that legalizeUndef has to be made public (though other methods used are also public). Also the methods required from the template type TargetT aren't clear without looking through the code. The current advanced phi lowering code depends on lowerPhiAssignments. That is a special case of lowerAssign that does some adhoc register allocation. The current adhoc register allocation doesn't work as well when a target may need to spill more than one register. Disable that optimization for ARM for now, until we have a better way that works for ARM, and enable O2 cross testing on ARM. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1223133007 .
parent fbdd2440
......@@ -328,10 +328,10 @@ check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime
--toolchain-root $(TOOLCHAIN_ROOT) \
-i x8632,native,sse2 -i x8632,native,sse4.1,test_vector_ops \
-i x8632,sandbox,sse4.1,Om1 \
-i arm32,native,neon,Om1,simple_loop \
-i arm32,native,neon,Om1,mem_intrin \
-i arm32,native,neon,Om1,test_stacksave \
-i arm32,native,neon,Om1,test_strengthreduce
-i arm32,native,neon,simple_loop \
-i arm32,native,neon,mem_intrin \
-i arm32,native,neon,test_stacksave \
-i arm32,native,neon,test_strengthreduce
PNACL_BIN_PATH=$(PNACL_BIN_PATH) \
$(LLVM_SRC_PATH)/utils/lit/lit.py -sv crosstest/Output
endif
......
......@@ -390,7 +390,15 @@ void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
OutFlags.setFunctionSections(::FunctionSections);
OutFlags.setNumTranslationThreads(::NumThreads);
OutFlags.setOptLevel(::OLevel);
OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit);
if (::TargetArch == Target_ARM32) {
// TODO(jvoung): We need lowerPhiAssignments to handle spilling
// more than one register, since some ARM lowerAssign sequences
// may require more than one register. For now, disable PhiEdgeSplit
// to avoid requiring lowerPhiAssignments.
OutFlags.setPhiEdgeSplit(false);
} else {
OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit);
}
OutFlags.setRandomSeed(::RandomSeed);
OutFlags.setShouldDoNopInsertion(::ShouldDoNopInsertion);
OutFlags.setShouldRandomizeRegAlloc(::RandomizeRegisterAllocation);
......
//===------ subzero/src/IcePhiLoweringImpl.h - Phi lowering -----*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This contains utilities for targets to lower Phis.
///
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICEPHILOWERINGIMPL_H
#define SUBZERO_SRC_ICEPHILOWERINGIMPL_H
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceOperand.h"
namespace Ice {
namespace PhiLowering {
// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
// preserve integrity of liveness analysis. This is needed for 32-bit
// targets. This assumes the 32-bit target has loOperand, hiOperand,
// and legalizeUndef methods. Undef values are also legalized, since
// loOperand() and hiOperand() don't expect Undef input.
template <class TargetT>
void prelowerPhis32Bit(TargetT *Target, CfgNode *Node, Cfg *Func) {
for (Inst &I : Node->getPhis()) {
auto Phi = llvm::dyn_cast<InstPhi>(&I);
if (Phi->isDeleted())
continue;
Variable *Dest = Phi->getDest();
if (Dest->getType() == IceType_i64) {
Variable *DestLo = llvm::cast<Variable>(Target->loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(Target->hiOperand(Dest));
InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
InstPhi *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi);
for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
Operand *Src = Phi->getSrc(I);
CfgNode *Label = Phi->getLabel(I);
Src = Target->legalizeUndef(Src);
PhiLo->addArgument(Target->loOperand(Src), Label);
PhiHi->addArgument(Target->hiOperand(Src), Label);
}
Node->getPhis().push_back(PhiLo);
Node->getPhis().push_back(PhiHi);
Phi->setDeleted();
}
}
}
} // end of namespace PhiLowering
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEPHILOWERINGIMPL_H
......@@ -24,6 +24,7 @@
#include "IceInstARM32.h"
#include "IceLiveness.h"
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
#include "IceRegistersARM32.h"
#include "IceTargetLoweringARM32.def"
#include "IceUtils.h"
......@@ -2410,12 +2411,8 @@ void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
_trap();
}
// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to
// preserve integrity of liveness analysis. Undef values are also
// turned into zeroes, since loOperand() and hiOperand() don't expect
// Undef input.
void TargetARM32::prelowerPhis() {
UnimplementedError(Func->getContext()->getFlags());
PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func);
}
// Lower the pre-ordered list of assignments into mov instructions.
......
......@@ -103,6 +103,7 @@ public:
bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const {
return CPUFeatures.hasFeature(I);
}
Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister);
protected:
explicit TargetARM32(Cfg *Func);
......@@ -146,7 +147,6 @@ protected:
Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
int32_t RegNum = Variable::NoRegister);
Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister);
Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister);
OperandARM32Mem *formMemoryOperand(Operand *Ptr, Type Ty);
Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
......
......@@ -159,6 +159,7 @@ public:
typename Traits::InstructionSet getInstructionSet() const final {
return InstructionSet;
}
Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister);
protected:
explicit TargetX86Base(Cfg *Func);
......@@ -230,7 +231,6 @@ protected:
Operand *legalize(Operand *From, LegalMask Allowed = Legal_All,
int32_t RegNum = Variable::NoRegister);
Variable *legalizeToVar(Operand *From, int32_t RegNum = Variable::NoRegister);
Operand *legalizeUndef(Operand *From, int32_t RegNum = Variable::NoRegister);
/// Legalize the first source operand for use in the cmp instruction.
Operand *legalizeSrc0ForCmp(Operand *Src0, Operand *Src1);
/// Turn a pointer operand into a memory operand that can be
......
......@@ -25,6 +25,7 @@
#include "IceGlobalInits.h"
#include "IceLiveness.h"
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
#include "IceUtils.h"
#include "llvm/Support/MathExtras.h"
......@@ -4696,30 +4697,8 @@ template <class Machine> void TargetX86Base<Machine>::prelowerPhis() {
// Pause constant blinding or pooling, blinding or pooling will be done later
// during phi lowering assignments
BoolFlagSaver B(RandomizationPoolingPaused, true);
CfgNode *Node = Context.getNode();
for (Inst &I : Node->getPhis()) {
auto Phi = llvm::dyn_cast<InstPhi>(&I);
if (Phi->isDeleted())
continue;
Variable *Dest = Phi->getDest();
if (Dest->getType() == IceType_i64) {
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
InstPhi *PhiLo = InstPhi::create(Func, Phi->getSrcSize(), DestLo);
InstPhi *PhiHi = InstPhi::create(Func, Phi->getSrcSize(), DestHi);
for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
Operand *Src = Phi->getSrc(I);
CfgNode *Label = Phi->getLabel(I);
Src = legalizeUndef(Src);
PhiLo->addArgument(loOperand(Src), Label);
PhiHi->addArgument(hiOperand(Src), Label);
}
Node->getPhis().push_back(PhiLo);
Node->getPhis().push_back(PhiHi);
Phi->setDeleted();
}
}
PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>(
this, Context.getNode(), Func);
}
bool isMemoryOperand(const Operand *Opnd) {
......
......@@ -158,6 +158,28 @@ entry:
; ARM32: bl {{.*}} ignore64BitArgNoInline
; ARM32: add sp, {{.*}} #16
define internal i32 @pass64BitUndefArg() {
entry:
%call = call i32 @ignore64BitArgNoInline(i64 0, i32 123, i64 undef)
ret i32 %call
}
; CHECK-LABEL: pass64BitUndefArg
; CHECK: sub esp
; CHECK: mov DWORD PTR{{.*}},0x7b
; CHECK: mov DWORD PTR{{.*}},0x0
; CHECK: call {{.*}} R_{{.*}} ignore64BitArgNoInline
; OPTM1-LABEL: pass64BitUndefArg
; OPTM1: sub esp
; OPTM1: mov DWORD PTR{{.*}},0x7b
; OPTM1: mov DWORD PTR{{.*}},0x0
; OPTM1: call {{.*}} R_{{.*}} ignore64BitArgNoInline
; ARM32-LABEL: pass64BitUndefArg
; ARM32: sub sp
; ARM32: movw {{.*}}, #0
; ARM32: str
; ARM32: movw {{.*}}, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline
define internal i64 @return64BitArg(i64 %padding, i64 %a) {
entry:
ret i64 %a
......@@ -1744,3 +1766,49 @@ if.end3: ; preds = %if.then2, %if.end
; OPTM1-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: icmpLt64Imm
; ARM32-NOT: cmp #{{[0-9a-f]+}},
define internal i64 @phi64Imm(i32 %x, i64 %y, i64 %z) {
entry:
%cond = icmp eq i32 %x, 88
br i1 %cond, label %branch1, label %branch2
branch1:
%tmp = add i64 %y, %z
br label %branch2
branch2:
%merge = phi i64 [ %tmp, %branch1 ], [ 20014547621496, %entry ]
ret i64 %merge
}
; CHECK-LABEL: phi64Imm
; CHECK: mov {{.*}},0x5678
; CHECK: mov {{.*}},0x1234
; OPTM1-LABEL: phi64Imm
; OPTM1: mov {{.*}},0x5678
; OPTM1: mov {{.*}},0x1234
; ARM32-LABEL: phi64Imm
; ARM32: movw {{.*}}, #22136 ; 0x5678
; ARM32: movw {{.*}}, #4660 ; 0x1234
define internal i64 @phi64Undef(i32 %x, i64 %y, i64 %z) {
entry:
%cond = icmp eq i32 %x, 88
br i1 %cond, label %branch1, label %branch2
branch1:
%tmp = add i64 %y, %z
br label %branch2
branch2:
%merge = phi i64 [ %tmp, %branch1 ], [ undef, %entry ]
ret i64 %merge
}
; CHECK-LABEL: phi64Undef
; CHECK: mov {{.*}},0x0
; CHECK: mov {{.*}},0x0
; OPTM1-LABEL: phi64Undef
; OPTM1: mov {{.*}},0x0
; OPTM1: mov {{.*}},0x0
; ARM32-LABEL: phi64Undef
; ARM32: mov {{.*}} #0
; ARM32: mov {{.*}} #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