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

Unified Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1506653002: Subzero: Add Non-SFI support for x86-32. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fill in part of the lit test Created 5 years 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
Index: src/IceTargetLoweringX86BaseImpl.h
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index d251e6a2756c66ed28d189e7e588ac38c7ed0771..be0494317888ef7112bdaccf2f5f281e20ac9252 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -324,13 +324,20 @@ TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
}
}
-template <class Machine> void TargetX86Base<Machine>::staticInit() {
+template <class Machine>
+void TargetX86Base<Machine>::staticInit(const ClFlags &Flags) {
Traits::initRegisterSet(&TypeToRegisterSet, &RegisterAliases, &ScratchRegs);
+ PcRelFixup = Traits::FixupKindPcRel;
+ RelFixup =
+ Flags.getUseNonsfi() ? Traits::FixupKindGotoff : Traits::FixupKindAbs;
}
template <class Machine> void TargetX86Base<Machine>::translateO2() {
TimerMarker T(TimerStack::TT_O2, Func);
+ if (!Traits::Is64Bit && Func->getContext()->getFlags().getUseNonsfi()) {
+ GotVar = Func->makeVariable(IceType_i32);
+ }
genTargetHelperCalls();
Func->dump("After target helper call insertion");
@@ -399,6 +406,7 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->genCode();
if (Func->hasError())
return;
+ initGotVar();
Func->dump("After x86 codegen");
// Register allocation. This requires instruction renumbering and full
@@ -457,6 +465,9 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
template <class Machine> void TargetX86Base<Machine>::translateOm1() {
TimerMarker T(TimerStack::TT_Om1, Func);
+ if (!Traits::Is64Bit && Func->getContext()->getFlags().getUseNonsfi()) {
+ GotVar = Func->makeVariable(IceType_i32);
+ }
genTargetHelperCalls();
// Do not merge Alloca instructions, and lay out the stack.
@@ -479,6 +490,7 @@ template <class Machine> void TargetX86Base<Machine>::translateOm1() {
Func->genCode();
if (Func->hasError())
return;
+ initGotVar();
John 2015/12/22 15:44:38 My first thought here was "a if (SFI) is missing."
Jim Stichnoth 2015/12/28 07:54:07 Done - renamed to initGotVarIfNeeded().
Func->dump("After initial x8632 codegen");
regAlloc(RAK_InfOnly);
@@ -804,7 +816,8 @@ void TargetX86Base<Machine>::emitVariable(const Variable *Var) const {
return;
}
if (Var->mustHaveReg()) {
- llvm_unreachable("Infinite-weight Variable has no register assigned");
+ llvm::report_fatal_error(
+ "Infinite-weight Variable has no register assigned");
}
const int32_t Offset = Var->getStackOffset();
int32_t BaseRegNum = Var->getBaseRegNum();
@@ -830,9 +843,10 @@ template <class Machine>
typename TargetX86Base<Machine>::Traits::Address
TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const {
if (Var->hasReg())
- llvm_unreachable("Stack Variable has a register assigned");
+ llvm::report_fatal_error("Stack Variable has a register assigned");
if (Var->mustHaveReg()) {
- llvm_unreachable("Infinite-weight Variable has no register assigned");
+ llvm::report_fatal_error(
+ "Infinite-weight Variable has no register assigned");
}
int32_t Offset = Var->getStackOffset();
int32_t BaseRegNum = Var->getBaseRegNum();
@@ -913,7 +927,7 @@ TargetX86Base<Machine>::loOperand(Operand *Operand) {
if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
auto *MemOperand = Traits::X86OperandMem::create(
Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
- Mem->getShift(), Mem->getSegmentRegister());
+ Mem->getShift(), Mem->getSegmentRegister(), Mem->getIsPIC());
// Test if we should randomize or pool the offset, if so randomize it or
// pool it then create mem operand with the blinded/pooled constant.
// Otherwise, return the mem operand as ordinary mem operand.
@@ -953,7 +967,7 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
}
auto *MemOperand = Traits::X86OperandMem::create(
Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
- Mem->getShift(), Mem->getSegmentRegister());
+ Mem->getShift(), Mem->getSegmentRegister(), Mem->getIsPIC());
// Test if the Offset is an eligible i32 constants for randomization and
// pooling. Blind/pool it if it is. Otherwise return as oridinary mem
// operand.
@@ -970,6 +984,21 @@ TargetX86Base<Machine>::getRegisterSet(RegSetMask Include,
return Traits::getRegisterSet(Include, Exclude);
}
+template <class Machine> void TargetX86Base<Machine>::initGotVar() {
+ if (Traits::Is64Bit) {
+ // Probably no implementation is needed, but error to be safe for now.
+ llvm::report_fatal_error("Need to implement initGotVar() for 64-bit.");
+ }
+ if (!Func->getContext()->getFlags().getUseNonsfi())
+ return;
+ // Insert the GotVar assignment as the very first lowered instruction. Later,
+ // it will be moved into the right place - after the stack frame is set up but
+ // before in-args are copied into registers.
+ Context.init(Func->getEntryNode());
+ Context.setInsertPoint(Context.getCur());
+ Context.insert(InstX86GetIP<Machine>::create(Func, GotVar));
+}
+
template <class Machine>
void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
// Conservatively require the stack to be aligned. Some stack adjustment
@@ -3975,6 +4004,11 @@ void TargetX86Base<Machine>::lowerCountZeros(bool Cttz, Type Ty, Variable *Dest,
template <class Machine>
void TargetX86Base<Machine>::typedLoad(Type Ty, Variable *Dest, Variable *Base,
Constant *Offset) {
+ // If Offset is a ConstantRelocatable in Non-SFI mode, we will need to
+ // legalize Mem properly.
+ if (Offset)
+ assert(!llvm::isa<ConstantRelocatable>(Offset));
+
auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
@@ -3988,6 +4022,11 @@ void TargetX86Base<Machine>::typedLoad(Type Ty, Variable *Dest, Variable *Base,
template <class Machine>
void TargetX86Base<Machine>::typedStore(Type Ty, Variable *Value,
Variable *Base, Constant *Offset) {
+ // If Offset is a ConstantRelocatable in Non-SFI mode, we will need to
+ // legalize Mem properly.
+ if (Offset)
+ assert(!llvm::isa<ConstantRelocatable>(Offset));
+
auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
@@ -4291,9 +4330,9 @@ inline void dumpAddressOpt(const Cfg *Func,
<< ", Relocatable=" << Relocatable << "\n";
}
-inline bool matchAssign(const VariablesMetadata *VMetadata, Variable *&Var,
- ConstantRelocatable *&Relocatable, int32_t &Offset,
- const Inst *&Reason) {
+inline bool matchAssign(const VariablesMetadata *VMetadata, Variable *GotVar,
+ Variable *&Var, ConstantRelocatable *&Relocatable,
+ int32_t &Offset, const Inst *&Reason) {
// Var originates from Var=SrcVar ==> set Var:=SrcVar
if (Var == nullptr)
return false;
@@ -4320,7 +4359,7 @@ inline bool matchAssign(const VariablesMetadata *VMetadata, Variable *&Var,
return true;
} else if (auto *AddReloc = llvm::dyn_cast<ConstantRelocatable>(SrcOp)) {
if (Relocatable == nullptr) {
- Var = nullptr;
+ Var = GotVar;
Relocatable = AddReloc;
Reason = VarAssign;
return true;
@@ -4439,7 +4478,9 @@ inline bool matchShiftedIndex(const VariablesMetadata *VMetadata,
return false;
}
-inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
+inline bool matchOffsetBase(const VariablesMetadata *VMetadata,
+ Variable *GotVar, Variable *&Base,
+ Variable *&BaseOther,
ConstantRelocatable *&Relocatable, int32_t &Offset,
const Inst *&Reason) {
// Base is Base=Var+Const || Base is Base=Const+Var ==>
@@ -4490,6 +4531,8 @@ inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
NewRelocatable = Reloc0;
else if (Reloc1)
NewRelocatable = Reloc1;
+ if (NewRelocatable && BaseOther && GotVar)
+ return false;
// Compute the updated constant offset.
if (Const0) {
int32_t MoreOffset = IsAdd ? Const0->getValue() : -Const0->getValue();
@@ -4505,6 +4548,10 @@ inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
}
// Update the computed address parameters once we are sure optimization
// is valid.
+ if (NewRelocatable && GotVar) {
+ assert(BaseOther == nullptr);
+ BaseOther = GotVar;
+ }
Base = NewBase;
Offset = NewOffset;
Relocatable = NewRelocatable;
@@ -4522,7 +4569,7 @@ inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
// Base is a Variable,
// Index == nullptr,
// Shift == 0
-inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
+inline bool computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *GotVar,
ConstantRelocatable *&Relocatable,
int32_t &Offset, Variable *&Base,
Variable *&Index, uint16_t &Shift) {
@@ -4553,7 +4600,7 @@ inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
Reason = nullptr;
}
// Update Base and Index to follow through assignments to definitions.
- if (matchAssign(VMetadata, Base, Relocatable, Offset, Reason)) {
+ if (matchAssign(VMetadata, GotVar, Base, Relocatable, Offset, Reason)) {
// Assignments of Base from a Relocatable or ConstantInt32 can result
// in Base becoming nullptr. To avoid code duplication in this loop we
// prefer that Base be non-nullptr if possible.
@@ -4561,7 +4608,7 @@ inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
std::swap(Base, Index);
continue;
}
- if (matchAssign(VMetadata, Index, Relocatable, Offset, Reason))
+ if (matchAssign(VMetadata, GotVar, Index, Relocatable, Offset, Reason))
continue;
if (!MockBounds) {
@@ -4590,10 +4637,11 @@ inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
// Update Offset to reflect additions/subtractions with constants and
// relocatables.
// TODO: consider overflow issues with respect to Offset.
- if (matchOffsetBase(VMetadata, Base, Relocatable, Offset, Reason))
+ if (matchOffsetBase(VMetadata, GotVar, Base, Index, Relocatable, Offset,
+ Reason))
continue;
- if (Shift == 0 &&
- matchOffsetBase(VMetadata, Index, Relocatable, Offset, Reason))
+ if (Shift == 0 && matchOffsetBase(VMetadata, GotVar, Index, Base,
+ Relocatable, Offset, Reason))
continue;
// TODO(sehr, stichnot): Handle updates of Index with Shift != 0.
// Index is Index=Var+Const ==>
@@ -4604,6 +4652,12 @@ inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
// set Index=Var, Offset-=(Const<<Shift)
break;
} while (Reason);
+ // Undo any addition of GotVar. It will be added back when the mem operand is
+ // legalized.
+ if (Base == GotVar)
+ Base = nullptr;
+ if (Index == GotVar)
+ Index = nullptr;
return AddressWasOptimized;
}
@@ -4669,7 +4723,7 @@ template <class Machine>
void TargetX86Base<Machine>::lowerLoad(const InstLoad *Load) {
// A Load instruction can be treated the same as an Assign instruction, after
// the source operand is transformed into an Traits::X86OperandMem operand.
- // Note that the address mode optimization already creates an
+ // Note that the address mode optimization already creates a
// Traits::X86OperandMem operand, so it doesn't need another level of
// transformation.
Variable *DestLoad = Load->getDest();
@@ -4692,10 +4746,10 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
// computeAddressOpt only works at the level of Variables and Constants, not
// other Traits::X86OperandMem, so there should be no mention of segment
// registers there either.
- const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
- Traits::X86OperandMem::DefaultSegment;
+ constexpr auto SegmentReg = Traits::X86OperandMem::DefaultSegment;
auto *Base = llvm::dyn_cast<Variable>(Addr);
- if (computeAddressOpt(Func, Inst, Relocatable, Offset, Base, Index, Shift)) {
+ if (computeAddressOpt(Func, Inst, GotVar, Relocatable, Offset, Base, Index,
+ Shift)) {
Inst->setDeleted();
Constant *OffsetOp = nullptr;
if (Relocatable == nullptr) {
@@ -4705,6 +4759,8 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
Relocatable->getName(),
Relocatable->getSuppressMangling());
}
+ // The new mem operand is created without IsPIC being set, because
+ // computeAddressOpt() doesn't include GotVar in its final result.
Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp,
Index, Shift, SegmentReg);
Context.insert<InstLoad>(Dest, Addr);
@@ -4999,9 +5055,9 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
// computeAddressOpt only works at the level of Variables and Constants, not
// other Traits::X86OperandMem, so there should be no mention of segment
// registers there either.
- const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
- Traits::X86OperandMem::DefaultSegment;
- if (computeAddressOpt(Func, Inst, Relocatable, Offset, Base, Index, Shift)) {
+ constexpr auto SegmentReg = Traits::X86OperandMem::DefaultSegment;
John 2015/12/22 15:44:38 I personally like this idiom, but this is an "unsa
Jim Stichnoth 2015/12/28 07:54:07 OK, I modified it such that the fully written out
+ if (computeAddressOpt(Func, Inst, GotVar, Relocatable, Offset, Base, Index,
+ Shift)) {
Inst->setDeleted();
Constant *OffsetOp = nullptr;
if (Relocatable == nullptr) {
@@ -5011,6 +5067,8 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
Relocatable->getName(),
Relocatable->getSuppressMangling());
}
+ // The new mem operand is created without IsPIC being set, because
+ // computeAddressOpt() doesn't include GotVar in its final result.
Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp,
Index, Shift, SegmentReg);
auto *NewStore = Context.insert<InstStore>(Data, Addr);
@@ -5071,15 +5129,16 @@ void TargetX86Base<Machine>::lowerCaseCluster(const CaseCluster &Case,
constexpr RelocOffsetT RelocOffset = 0;
constexpr bool SuppressMangling = true;
+ const bool IsPIC = Ctx->getFlags().getUseNonsfi();
IceString MangledName = Ctx->mangleName(Func->getFunctionName());
- Constant *Base = Ctx->getConstantSym(
+ Variable *Base = IsPIC ? legalizeToReg(GotVar) : nullptr;
+ Constant *Offset = Ctx->getConstantSym(
RelocOffset, InstJumpTable::makeName(MangledName, JumpTable->getId()),
SuppressMangling);
- Constant *Offset = nullptr;
uint16_t Shift = typeWidthInBytesLog2(getPointerType());
- // TODO(ascull): remove need for legalize by allowing null base in memop
+ constexpr auto Segment = Traits::X86OperandMem::DefaultSegment;
auto *TargetInMemory = Traits::X86OperandMem::create(
- Func, getPointerType(), legalizeToReg(Base), Offset, Index, Shift);
+ Func, getPointerType(), Base, Offset, Index, Shift, Segment, IsPIC);
Variable *Target = nullptr;
_mov(Target, TargetInMemory);
lowerIndirectJump(Target);
@@ -5410,8 +5469,31 @@ void TargetX86Base<Machine>::lowerOther(const Inst *Instr) {
/// 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.
+/// since loOperand() and hiOperand() don't expect Undef input. Also, in
+/// Non-SFI mode, add a FakeUse(GotVar) for every pooled constant operand.
template <class Machine> void TargetX86Base<Machine>::prelowerPhis() {
+ if (Ctx->getFlags().getUseNonsfi()) {
+ assert(GotVar);
+ CfgNode *Node = Context.getNode();
+ uint32_t GotVarUseCount = 0;
+ for (Inst &I : Node->getPhis()) {
+ auto *Phi = llvm::dyn_cast<InstPhi>(&I);
+ if (Phi->isDeleted())
+ continue;
+ for (SizeT I = 0; I < Phi->getSrcSize(); ++I) {
+ Operand *Src = Phi->getSrc(I);
+ // TODO(stichnot): This over-counts for +0.0, and under-counts for other
+ // kinds of pooling.
+ if (llvm::isa<ConstantRelocatable>(Src) ||
+ llvm::isa<ConstantFloat>(Src) || llvm::isa<ConstantDouble>(Src)) {
+ ++GotVarUseCount;
+ }
+ }
+ }
+ if (GotVarUseCount) {
+ Node->getInsts().push_front(InstFakeUse::create(Func, GotVar));
+ }
+ }
if (Traits::Is64Bit) {
// On x86-64 we don't need to prelower phis -- the architecture can handle
// 64-bit integer natively.
@@ -5892,7 +5974,8 @@ Variable *TargetX86Base<Machine>::copyToReg(Operand *Src, int32_t RegNum) {
template <class Machine>
Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
int32_t RegNum) {
- Type Ty = From->getType();
+ const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi();
+ const Type Ty = From->getType();
// Assert that a physical register is allowed. To date, all calls to
// legalize() allow a physical register. If a physical register needs to be
// explicitly disallowed, then new code will need to be written to force a
@@ -5926,6 +6009,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
// Base and Index components are in physical registers.
Variable *Base = Mem->getBase();
Variable *Index = Mem->getIndex();
+ Constant *Offset = Mem->getOffset();
Variable *RegBase = nullptr;
Variable *RegIndex = nullptr;
if (Base) {
@@ -5936,10 +6020,27 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
RegIndex = llvm::cast<Variable>(
legalize(Index, Legal_Reg | Legal_Rematerializable));
}
+ // For Non-SFI mode, if the Offset field is a ConstantRelocatable, we
+ // replace either Base or Index with a legalized GotVar. At emission time,
+ // the ConstantRelocatable will be emitted with the @GOTOFF relocation.
+ bool NeedPIC = false;
+ if (UseNonsfi && !Mem->getIsPIC() && Offset &&
+ llvm::isa<ConstantRelocatable>(Offset)) {
+ assert(!(Allowed & Legal_AddrAbs));
+ NeedPIC = true;
+ if (RegBase == nullptr) {
+ RegBase = legalizeToReg(GotVar);
+ } else if (RegIndex == nullptr) {
+ RegIndex = legalizeToReg(GotVar);
+ } else {
+ llvm::report_fatal_error(
+ "Either Base or Index must be unused in Non-SFI mode");
+ }
+ }
if (Base != RegBase || Index != RegIndex) {
- Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(),
- RegIndex, Mem->getShift(),
- Mem->getSegmentRegister());
+ Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Offset, RegIndex,
+ Mem->getShift(),
+ Mem->getSegmentRegister(), NeedPIC);
}
// For all Memory Operands, we do randomization/pooling here
@@ -5950,6 +6051,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
return From;
}
+
if (auto *Const = llvm::dyn_cast<Constant>(From)) {
if (llvm::isa<ConstantUndef>(Const)) {
From = legalizeUndef(Const, RegNum);
@@ -5978,6 +6080,20 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
}
+ // If the operand is a ConstantRelocatable, and Legal_AddrAbs is not
+ // specified, and UseNonsfi is indicated, we need to add GotVar.
+ if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Const)) {
+ if (UseNonsfi && !(Allowed & Legal_AddrAbs)) {
+ assert(Ty == IceType_i32);
+ Variable *RegBase = legalizeToReg(GotVar);
+ Variable *NewVar = makeReg(Ty, RegNum);
+ auto *Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, CR);
+ Mem->setIsPIC();
+ _lea(NewVar, Mem);
+ From = NewVar;
+ }
+ }
+
// Convert a scalar floating point constant into an explicit memory
// operand.
if (isScalarFloatingType(Ty)) {
@@ -5988,13 +6104,16 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
if (Utils::isPositiveZero(ConstDouble->getValue()))
return makeZeroedRegister(Ty, RegNum);
}
- Variable *Base = nullptr;
+ Variable *Base = UseNonsfi ? legalizeToReg(GotVar) : nullptr;
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx);
llvm::cast<Constant>(From)->setShouldBePooled(true);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
- From = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+ auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+ if (UseNonsfi)
+ Mem->setIsPIC();
+ From = Mem;
}
bool NeedsReg = false;
if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
@@ -6008,6 +6127,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
return From;
}
+
if (auto *Var = llvm::dyn_cast<Variable>(From)) {
// Check if the variable is guaranteed a physical register. This can happen
// either when the variable is pre-colored or when it is assigned infinite
@@ -6036,7 +6156,8 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
return From;
}
- llvm_unreachable("Unhandled operand kind in legalize()");
+
+ llvm::report_fatal_error("Unhandled operand kind in legalize()");
return From;
}
@@ -6104,7 +6225,7 @@ TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
// offset, we will work on the whole memory operand later as one entity
// later, this save one instruction. By turning blinding and pooling off,
// we guarantee legalize(Offset) will return a Constant*.
- {
+ if (!llvm::isa<ConstantRelocatable>(Offset)) {
BoolFlagSaver B(RandomizationPoolingPaused, true);
Offset = llvm::cast<Constant>(legalize(Offset));
@@ -6113,6 +6234,11 @@ TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
assert(llvm::isa<ConstantInteger32>(Offset) ||
llvm::isa<ConstantRelocatable>(Offset));
}
+ // Not completely sure whether it's OK to leave IsPIC unset when creating
+ // the mem operand. If DoLegalize is true, it will definitely be applied
+ // during the legalize() call, but perhaps not during the
+ // randomizeOrPoolImmediate() call. In any case, the emit routines will
+ // assert that PIC legalization has been applied.
Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
}
// Do legalization, which contains randomization/pooling or do
@@ -6181,7 +6307,7 @@ void TargetX86Base<Machine>::emit(const ConstantInteger32 *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- Str << getConstantPrefix() << C->getValue();
+ Str << "$" << C->getValue();
}
template <class Machine>
@@ -6192,7 +6318,7 @@ void TargetX86Base<Machine>::emit(const ConstantInteger64 *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- Str << getConstantPrefix() << C->getValue();
+ Str << "$" << C->getValue();
}
}
@@ -6217,6 +6343,16 @@ void TargetX86Base<Machine>::emit(const ConstantUndef *) const {
llvm::report_fatal_error("undef value encountered by emitter.");
}
+template <class Machine>
+void TargetX86Base<Machine>::emit(const ConstantRelocatable *C) const {
+ if (!BuildDefs::dump())
+ return;
+ assert(!Ctx->getFlags().getUseNonsfi());
+ Ostream &Str = Ctx->getStrEmit();
+ Str << "$";
+ emitWithoutPrefix(C);
+}
+
/// Randomize or pool an Immediate.
template <class Machine>
Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
@@ -6280,9 +6416,13 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
constexpr bool SuppressMangling = true;
Constant *Symbol =
Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
+ const bool UseNonsfi = Ctx->getFlags().getUseNonsfi();
+ Variable *Base = UseNonsfi ? legalizeToReg(GotVar) : nullptr;
typename Traits::X86OperandMem *MemOperand =
- Traits::X86OperandMem::create(Func, Immediate->getType(), nullptr,
+ Traits::X86OperandMem::create(Func, Immediate->getType(), Base,
Symbol);
+ if (UseNonsfi)
+ MemOperand->setIsPIC();
_mov(Reg, MemOperand);
return Reg;
}
@@ -6377,9 +6517,13 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
constexpr bool SuppressMangling = true;
Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
SuppressMangling);
+ const bool UseNonsfi = Ctx->getFlags().getUseNonsfi();
+ Variable *Base = UseNonsfi ? legalizeToReg(GotVar) : nullptr;
typename Traits::X86OperandMem *SymbolOperand =
Traits::X86OperandMem::create(
- Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
+ Func, MemOperand->getOffset()->getType(), Base, Symbol);
+ if (UseNonsfi)
+ SymbolOperand->setIsPIC();
_mov(RegTemp, SymbolOperand);
// If we have a base variable here, we should add the lea instruction
// to add the value of the base variable to RegTemp. If there is no

Powered by Google App Engine
This is Rietveld 408576698