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: Code review changes Created 4 years, 12 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/IceTargetLoweringX86Base.h ('k') | tests_lit/llvm2ice_tests/adv-switch-opt.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringX86BaseImpl.h
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 04d9cdc00d08f884ecb4204804ed2cf07f8e024f..5127768437978d0623cfa2e52d4ea0e0767bfee5 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -323,13 +323,19 @@ TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func)
}
}
-template <typename TraitsType> void TargetX86Base<TraitsType>::staticInit() {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::staticInit(const ClFlags &Flags) {
Traits::initRegisterSet(&TypeToRegisterSet, &RegisterAliases, &ScratchRegs);
+ PcRelFixup = Traits::FK_PcRel;
+ AbsFixup = Flags.getUseNonsfi() ? Traits::FK_Gotoff : Traits::FK_Abs;
}
template <typename TraitsType> void TargetX86Base<TraitsType>::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");
@@ -398,6 +404,7 @@ template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() {
Func->genCode();
if (Func->hasError())
return;
+ initGotVarIfNeeded();
Func->dump("After x86 codegen");
// Register allocation. This requires instruction renumbering and full
@@ -456,6 +463,9 @@ template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() {
template <typename TraitsType> void TargetX86Base<TraitsType>::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.
@@ -478,6 +488,7 @@ template <typename TraitsType> void TargetX86Base<TraitsType>::translateOm1() {
Func->genCode();
if (Func->hasError())
return;
+ initGotVarIfNeeded();
Func->dump("After initial x8632 codegen");
regAlloc(RAK_InfOnly);
@@ -803,7 +814,8 @@ void TargetX86Base<TraitsType>::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();
@@ -829,9 +841,10 @@ template <typename TraitsType>
typename TargetX86Base<TraitsType>::X86Address
TargetX86Base<TraitsType>::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();
@@ -910,7 +923,7 @@ TargetX86Base<TraitsType>::loOperand(Operand *Operand) {
if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Operand)) {
auto *MemOperand = 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.
@@ -950,7 +963,7 @@ TargetX86Base<TraitsType>::hiOperand(Operand *Operand) {
}
auto *MemOperand = 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.
@@ -968,6 +981,23 @@ TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include,
}
template <typename TraitsType>
+void TargetX86Base<TraitsType>::initGotVarIfNeeded() {
+ if (!Func->getContext()->getFlags().getUseNonsfi())
+ return;
+ if (Traits::Is64Bit) {
+ // Probably no implementation is needed, but error to be safe for now.
+ llvm::report_fatal_error(
+ "Need to implement initGotVarIfNeeded() for 64-bit.");
+ }
+ // 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<typename Traits::Insts::GetIP>(GotVar);
+}
+
+template <typename TraitsType>
void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Inst) {
// Conservatively require the stack to be aligned. Some stack adjustment
// operations implemented below assume that the stack is aligned before the
@@ -3984,6 +4014,11 @@ void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty,
template <typename TraitsType>
void TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
@@ -3997,6 +4032,11 @@ void TargetX86Base<TraitsType>::typedLoad(Type Ty, Variable *Dest,
template <typename TraitsType>
void TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
@@ -4306,9 +4346,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;
@@ -4335,7 +4375,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;
@@ -4454,7 +4494,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 ==>
@@ -4505,6 +4547,8 @@ inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
NewRelocatable = Reloc0;
else if (Reloc1)
NewRelocatable = Reloc1;
+ if ((Reloc0 || Reloc1) && BaseOther && GotVar)
+ return false;
// Compute the updated constant offset.
if (Const0) {
int32_t MoreOffset = IsAdd ? Const0->getValue() : -Const0->getValue();
@@ -4520,6 +4564,10 @@ inline bool matchOffsetBase(const VariablesMetadata *VMetadata, Variable *&Base,
}
// Update the computed address parameters once we are sure optimization
// is valid.
+ if ((Reloc0 || Reloc1) && GotVar) {
+ assert(BaseOther == nullptr);
+ BaseOther = GotVar;
+ }
Base = NewBase;
Offset = NewOffset;
Relocatable = NewRelocatable;
@@ -4537,7 +4585,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) {
@@ -4568,7 +4616,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.
@@ -4576,7 +4624,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) {
@@ -4605,10 +4653,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 ==>
@@ -4619,6 +4668,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;
}
@@ -4683,10 +4738,9 @@ void TargetX86Base<TraitsType>::doMockBoundsCheck(Operand *Opnd) {
template <typename TraitsType>
void TargetX86Base<TraitsType>::lowerLoad(const InstLoad *Load) {
// A Load instruction can be treated the same as an Assign instruction, after
- // the source operand is transformed into an X86OperandMem operand.
- // Note that the address mode optimization already creates an
- // X86OperandMem operand, so it doesn't need another level of
- // transformation.
+ // the source operand is transformed into an X86OperandMem operand. Note that
+ // the address mode optimization already creates an X86OperandMem operand, so
+ // it doesn't need another level of transformation.
Variable *DestLoad = Load->getDest();
Type Ty = DestLoad->getType();
Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty);
@@ -4708,9 +4762,10 @@ void TargetX86Base<TraitsType>::doAddressOptLoad() {
// computeAddressOpt only works at the level of Variables and Constants, not
// other X86OperandMem, so there should be no mention of segment
// registers there either.
- const SegmentRegisters SegmentReg = X86OperandMem::DefaultSegment;
+ constexpr auto SegmentReg = X86OperandMem::SegmentRegisters::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) {
@@ -4720,6 +4775,8 @@ void TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp, Index,
Shift, SegmentReg);
Context.insert<InstLoad>(Dest, Addr);
@@ -5011,8 +5068,9 @@ void TargetX86Base<TraitsType>::doAddressOptStore() {
// computeAddressOpt only works at the level of Variables and Constants, not
// other X86OperandMem, so there should be no mention of segment
// registers there either.
- const SegmentRegisters SegmentReg = X86OperandMem::DefaultSegment;
- if (computeAddressOpt(Func, Inst, Relocatable, Offset, Base, Index, Shift)) {
+ constexpr auto SegmentReg = X86OperandMem::SegmentRegisters::DefaultSegment;
+ if (computeAddressOpt(Func, Inst, GotVar, Relocatable, Offset, Base, Index,
+ Shift)) {
Inst->setDeleted();
Constant *OffsetOp = nullptr;
if (Relocatable == nullptr) {
@@ -5022,6 +5080,8 @@ void TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Data->getType(), Base, OffsetOp, Index,
Shift, SegmentReg);
auto *NewStore = Context.insert<InstStore>(Data, Addr);
@@ -5083,15 +5143,16 @@ void TargetX86Base<TraitsType>::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 = X86OperandMem::SegmentRegisters::DefaultSegment;
auto *TargetInMemory = 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);
@@ -5417,8 +5478,31 @@ void TargetX86Base<TraitsType>::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 <typename TraitsType> void TargetX86Base<TraitsType>::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.
@@ -5901,7 +5985,8 @@ Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, int32_t RegNum) {
template <typename TraitsType>
Operand *TargetX86Base<TraitsType>::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
@@ -5935,6 +6020,7 @@ Operand *TargetX86Base<TraitsType>::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) {
@@ -5945,9 +6031,27 @@ Operand *TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
- Mem->getShift(), Mem->getSegmentRegister());
+ Mem = X86OperandMem::create(Func, Ty, RegBase, Offset, RegIndex,
+ Mem->getShift(), Mem->getSegmentRegister(),
+ NeedPIC);
}
// For all Memory Operands, we do randomization/pooling here
@@ -5958,6 +6062,7 @@ Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed,
}
return From;
}
+
if (auto *Const = llvm::dyn_cast<Constant>(From)) {
if (llvm::isa<ConstantUndef>(Const)) {
From = legalizeUndef(Const, RegNum);
@@ -5988,6 +6093,20 @@ Operand *TargetX86Base<TraitsType>::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)) {
@@ -5998,13 +6117,16 @@ Operand *TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Ty, Base, Offset);
+ auto *Mem = X86OperandMem::create(Func, Ty, Base, Offset);
+ if (UseNonsfi)
+ Mem->setIsPIC();
+ From = Mem;
}
bool NeedsReg = false;
if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
@@ -6018,6 +6140,7 @@ Operand *TargetX86Base<TraitsType>::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
@@ -6046,7 +6169,8 @@ Operand *TargetX86Base<TraitsType>::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;
}
@@ -6116,7 +6240,7 @@ TargetX86Base<TraitsType>::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));
@@ -6125,6 +6249,11 @@ TargetX86Base<TraitsType>::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 = X86OperandMem::create(Func, Ty, Base, Offset);
}
// Do legalization, which contains randomization/pooling or do
@@ -6192,7 +6321,7 @@ void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- Str << getConstantPrefix() << C->getValue();
+ Str << "$" << C->getValue();
}
template <typename TraitsType>
@@ -6203,7 +6332,7 @@ void TargetX86Base<TraitsType>::emit(const ConstantInteger64 *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- Str << getConstantPrefix() << C->getValue();
+ Str << "$" << C->getValue();
}
}
@@ -6228,6 +6357,16 @@ void TargetX86Base<TraitsType>::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 <typename TraitsType>
Operand *
@@ -6292,8 +6431,12 @@ TargetX86Base<TraitsType>::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;
X86OperandMem *MemOperand =
- X86OperandMem::create(Func, Immediate->getType(), nullptr, Symbol);
+ X86OperandMem::create(Func, Immediate->getType(), Base, Symbol);
+ if (UseNonsfi)
+ MemOperand->setIsPIC();
_mov(Reg, MemOperand);
return Reg;
}
@@ -6385,8 +6528,12 @@ TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand,
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;
X86OperandMem *SymbolOperand = 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
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | tests_lit/llvm2ice_tests/adv-switch-opt.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698