| Index: src/IceTargetLoweringX86BaseImpl.h
|
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
|
| index af05b7b8872180186500ab6d53d36526bc7d7389..6b2582317030f2916bae115a882fe02c278a5480 100644
|
| --- a/src/IceTargetLoweringX86BaseImpl.h
|
| +++ b/src/IceTargetLoweringX86BaseImpl.h
|
| @@ -1506,6 +1506,7 @@ void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Instr) {
|
|
|
| template <typename TraitsType>
|
| void TargetX86Base<TraitsType>::lowerArguments() {
|
| + const bool OptM1 = Func->getOptLevel() == Opt_m1;
|
| VarList &Args = Func->getArgs();
|
| unsigned NumXmmArgs = 0;
|
| bool XmmSlotsRemain = true;
|
| @@ -1561,8 +1562,20 @@ void TargetX86Base<TraitsType>::lowerArguments() {
|
| Arg->setIsArg(false);
|
|
|
| Args[i] = RegisterArg;
|
| - Context.insert<InstAssign>(Arg, RegisterArg);
|
| + // When not Om1, do the assignment through a temporary, instead of directly
|
| + // from the pre-colored variable, so that a subsequent availabilityGet()
|
| + // call has a chance to work. (In Om1, don't bother creating extra
|
| + // instructions with extra variables to register-allocate.)
|
| + if (OptM1) {
|
| + Context.insert<InstAssign>(Arg, RegisterArg);
|
| + } else {
|
| + Variable *Tmp = makeReg(RegisterArg->getType());
|
| + Context.insert<InstAssign>(Tmp, RegisterArg);
|
| + Context.insert<InstAssign>(Arg, Tmp);
|
| + }
|
| }
|
| + if (!OptM1)
|
| + Context.availabilityUpdate();
|
| }
|
|
|
| /// Strength-reduce scalar integer multiplication by a constant (for i32 or
|
| @@ -2588,29 +2601,35 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) {
|
| ParameterAreaSizeBytes = Traits::applyStackAlignment(ParameterAreaSizeBytes);
|
| assert(ParameterAreaSizeBytes <= maxOutArgsSizeBytes());
|
| // Copy arguments that are passed on the stack to the appropriate stack
|
| - // locations.
|
| + // locations. We make sure legalize() is called on each argument at this
|
| + // point, to allow availabilityGet() to work.
|
| for (SizeT i = 0, NumStackArgs = StackArgs.size(); i < NumStackArgs; ++i) {
|
| - lowerStore(InstStore::create(Func, StackArgs[i], StackArgLocations[i]));
|
| + lowerStore(
|
| + InstStore::create(Func, legalize(StackArgs[i]), StackArgLocations[i]));
|
| }
|
| // Copy arguments to be passed in registers to the appropriate registers.
|
| for (SizeT i = 0, NumXmmArgs = XmmArgs.size(); i < NumXmmArgs; ++i) {
|
| - Variable *Reg =
|
| - legalizeToReg(XmmArgs[i], Traits::getRegisterForXmmArgNum(i));
|
| - // Generate a FakeUse of register arguments so that they do not get dead
|
| - // code eliminated as a result of the FakeKill of scratch registers after
|
| - // the call.
|
| - Context.insert<InstFakeUse>(Reg);
|
| + XmmArgs[i] =
|
| + legalizeToReg(legalize(XmmArgs[i]), Traits::getRegisterForXmmArgNum(i));
|
| }
|
| // Materialize moves for arguments passed in GPRs.
|
| for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) {
|
| const Type SignatureTy = GprArgs[i].first;
|
| - Operand *Arg = GprArgs[i].second;
|
| - Variable *Reg =
|
| + Operand *Arg = legalize(GprArgs[i].second);
|
| + GprArgs[i].second =
|
| legalizeToReg(Arg, Traits::getRegisterForGprArgNum(Arg->getType(), i));
|
| assert(SignatureTy == IceType_i64 || SignatureTy == IceType_i32);
|
| assert(SignatureTy == Arg->getType());
|
| (void)SignatureTy;
|
| - Context.insert<InstFakeUse>(Reg);
|
| + }
|
| + // Generate a FakeUse of register arguments so that they do not get dead code
|
| + // eliminated as a result of the FakeKill of scratch registers after the call.
|
| + // These need to be right before the call instruction.
|
| + for (auto *Arg : XmmArgs) {
|
| + Context.insert<InstFakeUse>(llvm::cast<Variable>(Arg));
|
| + }
|
| + for (auto &ArgPair : GprArgs) {
|
| + Context.insert<InstFakeUse>(llvm::cast<Variable>(ArgPair.second));
|
| }
|
| // Generate the call instruction. Assign its result to a temporary with high
|
| // register allocation weight.
|
|
|