Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1136793002: Handle ARM "ret void" and function alignment with proper padding. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: note moved to cpp Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 6691e1ed9c5a474a49f66f84d0fc2ef7d3bc1fa2..287e42dab33537604c52d985b2e65abfc1aaf544 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -30,6 +30,17 @@
namespace Ice {
+namespace {
+void UnimplementedError(const ClFlags &Flags) {
+ if (!Flags.getSkipUnimplemented()) {
+ // Use llvm_unreachable instead of report_fatal_error, which gives better
+ // stack traces.
+ llvm_unreachable("Not yet implemented");
+ abort();
+ }
+}
+} // end of anonymous namespace
+
TargetARM32::TargetARM32(Cfg *Func)
: TargetLowering(Func), UsesFramePointer(false) {
// TODO: Don't initialize IntegerRegisters and friends every time.
@@ -205,7 +216,8 @@ void TargetARM32::translateOm1() {
bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
(void)I;
(void)NextNode;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
+ return false;
}
IceString TargetARM32::RegNames[] = {
@@ -233,9 +245,9 @@ Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) {
Reg = Func->makeVariable(Ty);
Reg->setRegNum(RegNum);
PhysicalRegisters[Ty][RegNum] = Reg;
- // Specially mark SP as an "argument" so that it is considered
+ // Specially mark SP and LR as an "argument" so that it is considered
// live upon function entry.
- if (RegNum == RegARM32::Reg_sp) {
+ if (RegNum == RegARM32::Reg_sp || RegNum == RegARM32::Reg_lr) {
Func->addImplicitArg(Reg);
Reg->setIgnoreLiveness();
}
@@ -245,25 +257,42 @@ Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) {
void TargetARM32::emitVariable(const Variable *Var) const {
Ostream &Str = Ctx->getStrEmit();
- (void)Var;
- (void)Str;
- llvm::report_fatal_error("emitVariable: Not yet implemented");
+ if (Var->hasReg()) {
+ Str << getRegName(Var->getRegNum(), Var->getType());
+ return;
+ }
+ if (Var->getWeight().isInf()) {
+ llvm::report_fatal_error(
+ "Infinite-weight Variable has no register assigned");
+ }
+ int32_t Offset = Var->getStackOffset();
+ if (!hasFramePointer())
+ Offset += getStackAdjustment();
+ // TODO(jvoung): Handle out of range. Perhaps we need a scratch register
+ // to materialize a larger offset.
+ const bool SignExt = false;
+ if (!OperandARM32Mem::canHoldOffset(Var->getType(), SignExt, Offset)) {
+ llvm::report_fatal_error("Illegal stack offset");
+ }
+ const Type FrameSPTy = IceType_i32;
+ Str << "[" << getRegName(getFrameOrStackReg(), FrameSPTy) << ", " << Offset
+ << "]";
}
void TargetARM32::lowerArguments() {
- llvm::report_fatal_error("lowerArguments: Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
Type TargetARM32::stackSlotType() { return IceType_i32; }
void TargetARM32::addProlog(CfgNode *Node) {
(void)Node;
- llvm::report_fatal_error("addProlog: Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::addEpilog(CfgNode *Node) {
(void)Node;
- llvm::report_fatal_error("addEpilog: Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include,
@@ -305,7 +334,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) {
// restriction can be relaxed in some cases.
NeedsStackAlignment = true;
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) {
@@ -314,75 +343,75 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) {
llvm_unreachable("Unknown arithmetic operator");
break;
case InstArithmetic::Add:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::And:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Or:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Xor:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Sub:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Mul:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Shl:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Lshr:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Ashr:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Udiv:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Sdiv:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Urem:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Srem:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Fadd:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Fsub:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Fmul:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Fdiv:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstArithmetic::Frem:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
}
void TargetARM32::lowerAssign(const InstAssign *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerBr(const InstBr *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerCall(const InstCall *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerCast(const InstCast *Inst) {
@@ -392,39 +421,39 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
Func->setError("Cast type not supported");
return;
case InstCast::Sext: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
case InstCast::Zext: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
case InstCast::Trunc: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
case InstCast::Fptrunc:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstCast::Fpext: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
case InstCast::Fptosi:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstCast::Fptoui:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstCast::Sitofp:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
case InstCast::Uitofp: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
case InstCast::Bitcast: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
break;
}
}
@@ -432,72 +461,72 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::AtomicFence:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
case Intrinsics::AtomicFenceAll:
// NOTE: FenceAll should prevent and load/store from being moved
// across the fence (both atomic and non-atomic). The InstARM32Mfence
// instruction is currently marked coarsely as "HasSideEffects".
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
case Intrinsics::AtomicIsLockFree: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::AtomicLoad: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::AtomicRMW:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
case Intrinsics::AtomicStore: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Bswap: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Ctpop: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Ctlz: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Cttz: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Fabs: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Longjmp: {
@@ -542,7 +571,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
}
case Intrinsics::NaClReadTP: {
if (Ctx->getFlags().getUseSandboxing()) {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
} else {
InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
lowerCall(Call);
@@ -556,19 +585,19 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Sqrt: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Stacksave: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Stackrestore: {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
}
case Intrinsics::Trap:
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
return;
case Intrinsics::UnknownIntrinsic:
Func->setError("Should not be lowering UnknownIntrinsic");
@@ -579,17 +608,17 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
void TargetARM32::lowerLoad(const InstLoad *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::doAddressOptLoad() {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::randomlyInsertNop(float Probability) {
RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
if (RNG.getTrueWithProbability(Probability)) {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
}
@@ -598,27 +627,42 @@ void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) {
}
void TargetARM32::lowerRet(const InstRet *Inst) {
- (void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ Variable *Reg = nullptr;
+ if (Inst->hasRetValue()) {
+ UnimplementedError(Func->getContext()->getFlags());
+ }
+ // Add a ret instruction even if sandboxing is enabled, because
+ // addEpilog explicitly looks for a ret instruction as a marker for
+ // where to insert the frame removal instructions.
+ // addEpilog is responsible for restoring the "lr" register as needed
+ // prior to this ret instruction.
+ _ret(getPhysicalRegister(RegARM32::Reg_lr), Reg);
+ // Add a fake use of sp to make sure sp stays alive for the entire
+ // function. Otherwise post-call sp adjustments get dead-code
+ // eliminated. TODO: Are there more places where the fake use
+ // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not
+ // have a ret instruction.
+ Variable *SP = Func->getTarget()->getPhysicalRegister(RegARM32::Reg_sp);
+ Context.insert(InstFakeUse::create(Func, SP));
}
void TargetARM32::lowerSelect(const InstSelect *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerStore(const InstStore *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::doAddressOptStore() {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
(void)Inst;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
@@ -630,7 +674,7 @@ void TargetARM32::lowerUnreachable(const InstUnreachable * /*Inst*/) {
// turned into zeroes, since loOperand() and hiOperand() don't expect
// Undef input.
void TargetARM32::prelowerPhis() {
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
// Lower the pre-ordered list of assignments into mov instructions.
@@ -639,7 +683,7 @@ void TargetARM32::lowerPhiAssignments(CfgNode *Node,
const AssignList &Assignments) {
(void)Node;
(void)Assignments;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::postLower() {
@@ -647,7 +691,7 @@ void TargetARM32::postLower() {
return;
// Find two-address non-SSA instructions where Dest==Src0, and set
// the DestNonKillable flag to keep liveness analysis consistent.
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
void TargetARM32::makeRandomRegisterPermutation(
@@ -655,7 +699,7 @@ void TargetARM32::makeRandomRegisterPermutation(
const llvm::SmallBitVector &ExcludeRegisters) const {
(void)Permutation;
(void)ExcludeRegisters;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Func->getContext()->getFlags());
}
/* TODO(jvoung): avoid duplicate symbols with multiple targets.
@@ -673,7 +717,7 @@ TargetDataARM32::TargetDataARM32(GlobalContext *Ctx)
void TargetDataARM32::lowerGlobal(const VariableDeclaration &Var) const {
(void)Var;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Ctx->getFlags());
}
void TargetDataARM32::lowerGlobals(
@@ -699,7 +743,7 @@ void TargetDataARM32::lowerGlobals(
void TargetDataARM32::lowerConstants() const {
if (Ctx->getFlags().getDisableTranslation())
return;
- llvm::report_fatal_error("Not yet implemented");
+ UnimplementedError(Ctx->getFlags());
}
} // end of namespace Ice
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698