Delete trailing whitespace.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62307 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mikhail Glushenkov 2009-01-16 06:53:46 +00:00
parent a10f15949d
commit 5c1799b293
8 changed files with 420 additions and 420 deletions

View File

@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// Defines a registry template for discovering pluggable modules.
//
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_REGISTRY_H
@ -23,34 +23,34 @@ namespace llvm {
class SimpleRegistryEntry {
const char *Name, *Desc;
T *(*Ctor)();
public:
SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
: Name(N), Desc(D), Ctor(C)
{}
const char *getName() const { return Name; }
const char *getDesc() const { return Desc; }
T *instantiate() const { return Ctor(); }
};
/// Traits for registry entries. If using other than SimpleRegistryEntry, it
/// is necessary to define an alternate traits class.
template <typename T>
class RegistryTraits {
RegistryTraits(); // Do not implement.
public:
typedef SimpleRegistryEntry<T> entry;
/// nameof/descof - Accessors for name and description of entries. These are
// used to generate help for command-line options.
static const char *nameof(const entry &Entry) { return Entry.getName(); }
static const char *descof(const entry &Entry) { return Entry.getDesc(); }
};
/// A global registry used in conjunction with static constructors to make
/// pluggable components (like targets or garbage collectors) "just work" when
/// linked with an executable.
@ -59,37 +59,37 @@ namespace llvm {
public:
typedef U traits;
typedef typename U::entry entry;
class node;
class listener;
class iterator;
private:
Registry(); // Do not implement.
static void Announce(const entry &E) {
for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
Cur->registered(E);
}
friend class node;
static node *Head, *Tail;
friend class listener;
static listener *ListenerHead, *ListenerTail;
public:
class iterator;
/// Node in linked list of entries.
///
///
class node {
friend class iterator;
node *Next;
const entry& Val;
public:
node(const entry& V) : Next(0), Val(V) {
if (Tail)
@ -97,63 +97,63 @@ namespace llvm {
else
Head = this;
Tail = this;
Announce(V);
}
};
/// Iterators for registry entries.
///
///
class iterator {
const node *Cur;
public:
explicit iterator(const node *N) : Cur(N) {}
bool operator==(const iterator &That) const { return Cur == That.Cur; }
bool operator!=(const iterator &That) const { return Cur != That.Cur; }
iterator &operator++() { Cur = Cur->Next; return *this; }
const entry &operator*() const { return Cur->Val; }
const entry *operator->() const { return &Cur->Val; }
};
static iterator begin() { return iterator(Head); }
static iterator end() { return iterator(0); }
/// Abstract base class for registry listeners, which are informed when new
/// entries are added to the registry. Simply subclass and instantiate:
///
///
/// class CollectorPrinter : public Registry<Collector>::listener {
/// protected:
/// void registered(const Registry<Collector>::entry &e) {
/// cerr << "collector now available: " << e->getName() << "\n";
/// }
///
///
/// public:
/// CollectorPrinter() { init(); } // Print those already registered.
/// };
///
///
/// CollectorPrinter Printer;
///
///
class listener {
listener *Prev, *Next;
friend void Registry::Announce(const entry &E);
protected:
/// Called when an entry is added to the registry.
///
///
virtual void registered(const entry &) = 0;
/// Calls 'registered' for each pre-existing entry.
///
///
void init() {
for (iterator I = begin(), E = end(); I != E; ++I)
registered(*I);
}
public:
listener() : Prev(ListenerTail), Next(0) {
if (Prev)
@ -162,7 +162,7 @@ namespace llvm {
ListenerHead = this;
ListenerTail = this;
}
virtual ~listener() {
if (Next)
Next->Prev = Prev;
@ -174,79 +174,79 @@ namespace llvm {
ListenerHead = Next;
}
};
/// A static registration template. Use like such:
///
///
/// Registry<Collector>::Add<FancyGC>
/// X("fancy-gc", "Newfangled garbage collector.");
///
///
/// Use of this template requires that:
///
///
/// 1. The registered subclass has a default constructor.
//
//
/// 2. The registry entry type has a constructor compatible with this
/// signature:
///
///
/// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
///
///
/// If you have more elaborate requirements, then copy and modify.
///
///
template <typename V>
class Add {
entry Entry;
node Node;
static T *CtorFn() { return new V(); }
public:
Add(const char *Name, const char *Desc)
: Entry(Name, Desc, CtorFn), Node(Entry) {}
};
/// A command-line parser for a registry. Use like such:
///
///
/// static cl::opt<Registry<Collector>::entry, false,
/// Registry<Collector>::Parser>
/// GCOpt("gc", cl::desc("Garbage collector to use."),
/// cl::value_desc());
///
///
/// To make use of the value:
///
///
/// Collector *TheCollector = GCOpt->instantiate();
///
///
class Parser : public cl::parser<const typename U::entry*>, public listener{
typedef U traits;
typedef typename U::entry entry;
protected:
void registered(const entry &E) {
addLiteralOption(traits::nameof(E), &E, traits::descof(E));
}
public:
void initialize(cl::Option &O) {
listener::init();
cl::parser<const typename U::entry*>::initialize(O);
}
};
};
template <typename T, typename U>
typename Registry<T,U>::node *Registry<T,U>::Head;
template <typename T, typename U>
typename Registry<T,U>::node *Registry<T,U>::Tail;
template <typename T, typename U>
typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
template <typename T, typename U>
typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
}
#endif

View File

@ -22,14 +22,14 @@
namespace llvm {
class Module;
class TargetMachine;
struct TargetMachineRegistryEntry {
const char *Name;
const char *ShortDesc;
TargetMachine *(*CtorFn)(const Module &, const std::string &);
unsigned (*ModuleMatchQualityFn)(const Module &M);
unsigned (*JITMatchQualityFn)();
public:
TargetMachineRegistryEntry(const char *N, const char *SD,
TargetMachine *(*CF)(const Module &, const std::string &),
@ -38,12 +38,12 @@ namespace llvm {
: Name(N), ShortDesc(SD), CtorFn(CF), ModuleMatchQualityFn(MMF),
JITMatchQualityFn(JMF) {}
};
template<>
class RegistryTraits<TargetMachine> {
public:
typedef TargetMachineRegistryEntry entry;
static const char *nameof(const entry &Entry) { return Entry.Name; }
static const char *descof(const entry &Entry) { return Entry.ShortDesc; }
};
@ -67,12 +67,12 @@ namespace llvm {
/// themselves with the tool they are linked. Targets should define an
/// instance of this and implement the static methods described in the
/// TargetMachine comments.
/// The type 'TargetMachineImpl' should provide a constructor with two
/// The type 'TargetMachineImpl' should provide a constructor with two
/// parameters:
/// - const Module& M: the module that is being compiled:
/// - const std::string& FS: target-specific string describing target
/// - const std::string& FS: target-specific string describing target
/// flavour.
template<class TargetMachineImpl>
struct RegisterTarget {
RegisterTarget(const char *Name, const char *ShortDesc)
@ -85,7 +85,7 @@ namespace llvm {
private:
TargetMachineRegistry::entry Entry;
TargetMachineRegistry::node Node;
static TargetMachine *Allocator(const Module &M, const std::string &FS) {
return new TargetMachineImpl(M, FS);
}

View File

@ -10,7 +10,7 @@
// This file implements printing the assembly code for an Ocaml frametable.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GCs.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
@ -28,11 +28,11 @@ namespace {
public:
void beginAssembly(raw_ostream &OS, AsmPrinter &AP,
const TargetAsmInfo &TAI);
void finishAssembly(raw_ostream &OS, AsmPrinter &AP,
const TargetAsmInfo &TAI);
};
}
static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter>
@ -43,7 +43,7 @@ void llvm::linkOcamlGCPrinter() { }
static void EmitCamlGlobal(const Module &M, raw_ostream &OS, AsmPrinter &AP,
const TargetAsmInfo &TAI, const char *Id) {
const std::string &MId = M.getModuleIdentifier();
std::string Mangled;
Mangled += TAI.getGlobalPrefix();
Mangled += "caml";
@ -51,10 +51,10 @@ static void EmitCamlGlobal(const Module &M, raw_ostream &OS, AsmPrinter &AP,
Mangled.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
Mangled += "__";
Mangled += Id;
// Capitalize the first letter of the module name.
Mangled[Letter] = toupper(Mangled[Letter]);
if (const char *GlobalDirective = TAI.getGlobalDirective())
OS << GlobalDirective << Mangled << "\n";
OS << Mangled << ":\n";
@ -64,13 +64,13 @@ void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
const TargetAsmInfo &TAI) {
AP.SwitchToSection(TAI.getTextSection());
EmitCamlGlobal(getModule(), OS, AP, TAI, "code_begin");
AP.SwitchToSection(TAI.getDataSection());
EmitCamlGlobal(getModule(), OS, AP, TAI, "data_begin");
}
/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
///
///
/// extern "C" struct align(sizeof(intptr_t)) {
/// uint16_t NumDescriptors;
/// struct align(sizeof(intptr_t)) {
@ -80,11 +80,11 @@ void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
/// uint16_t LiveOffsets[NumLiveOffsets];
/// } Descriptors[NumDescriptors];
/// } caml${module}__frametable;
///
///
/// Note that this precludes programs from stack frames larger than 64K
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
///
void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
const TargetAsmInfo &TAI) {
const char *AddressDirective;
@ -99,19 +99,19 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
AP.SwitchToSection(TAI.getTextSection());
EmitCamlGlobal(getModule(), OS, AP, TAI, "code_end");
AP.SwitchToSection(TAI.getDataSection());
EmitCamlGlobal(getModule(), OS, AP, TAI, "data_end");
OS << AddressDirective << 0; // FIXME: Why does ocaml emit this??
AP.EOL();
AP.SwitchToSection(TAI.getDataSection());
EmitCamlGlobal(getModule(), OS, AP, TAI, "frametable");
for (iterator I = begin(), IE = end(); I != IE; ++I) {
GCFunctionInfo &FI = **I;
uint64_t FrameSize = FI.getFrameSize();
if (FrameSize >= 1<<16) {
cerr << "Function '" << FI.getFunction().getNameStart()
@ -120,10 +120,10 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
cerr << "(" << uintptr_t(&FI) << ")\n";
abort(); // Very rude!
}
OS << "\t" << TAI.getCommentString() << " live roots for "
<< FI.getFunction().getNameStart() << "\n";
for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
size_t LiveCount = FI.live_size(J);
if (LiveCount >= 1<<16) {
@ -132,27 +132,27 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
<< "Live root count " << LiveCount << " >= 65536.\n";
abort(); // Very rude!
}
OS << AddressDirective
<< TAI.getPrivateGlobalPrefix() << "label" << J->Num;
AP.EOL("call return address");
AP.EmitInt16(FrameSize);
AP.EOL("stack frame size");
AP.EmitInt16(LiveCount);
AP.EOL("live root count");
for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
KE = FI.live_end(J); K != KE; ++K) {
assert(K->StackOffset < 1<<16 &&
"GC root stack offset is outside of fixed stack frame and out "
"of range for ocaml GC!");
OS << "\t.word\t" << K->StackOffset;
AP.EOL("stack offset");
}
AP.EmitAlignment(AddressAlignLog);
}
}

View File

@ -9,11 +9,11 @@
//
// This file implements lowering for the llvm.gc* intrinsics compatible with
// Objective Caml 3.10.0, which uses a liveness-accurate static stack map.
//
//
// The frametable emitter is in OcamlGCPrinter.cpp.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GCs.h"
#include "llvm/CodeGen/GCStrategy.h"

File diff suppressed because it is too large Load Diff

View File

@ -36,26 +36,26 @@
using namespace llvm;
namespace {
class VISIBILITY_HIDDEN ShadowStackGC : public GCStrategy {
/// RootChain - This is the global linked-list that contains the chain of GC
/// roots.
GlobalVariable *Head;
/// StackEntryTy - Abstract type of a link in the shadow stack.
///
///
const StructType *StackEntryTy;
/// Roots - GC roots in the current function. Each is a pair of the
/// intrinsic call and its corresponding alloca.
std::vector<std::pair<CallInst*,AllocaInst*> > Roots;
public:
ShadowStackGC();
bool initializeCustomLowering(Module &M);
bool performCustomLowering(Function &F);
private:
bool IsNullValue(Value *V);
Constant *GetFrameMap(Function &F);
@ -68,58 +68,58 @@ namespace {
};
}
static GCRegistry::Add<ShadowStackGC>
X("shadow-stack", "Very portable GC for uncooperative code generators");
namespace {
/// EscapeEnumerator - This is a little algorithm to find all escape points
/// from a function so that "finally"-style code can be inserted. In addition
/// to finding the existing return and unwind instructions, it also (if
/// necessary) transforms any call instructions into invokes and sends them to
/// a landing pad.
///
///
/// It's wrapped up in a state machine using the same transform C# uses for
/// 'yield return' enumerators, This transform allows it to be non-allocating.
class VISIBILITY_HIDDEN EscapeEnumerator {
Function &F;
const char *CleanupBBName;
// State.
int State;
Function::iterator StateBB, StateE;
IRBuilder<> Builder;
public:
EscapeEnumerator(Function &F, const char *N = "cleanup")
: F(F), CleanupBBName(N), State(0) {}
IRBuilder<> *Next() {
switch (State) {
default:
return 0;
case 0:
StateBB = F.begin();
StateE = F.end();
State = 1;
case 1:
// Find all 'return' and 'unwind' instructions.
while (StateBB != StateE) {
BasicBlock *CurBB = StateBB++;
// Branches and invokes do not escape, only unwind and return do.
TerminatorInst *TI = CurBB->getTerminator();
if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI))
continue;
Builder.SetInsertPoint(TI->getParent(), TI);
return &Builder;
}
State = 2;
// Find all 'call' instructions.
SmallVector<Instruction*,16> Calls;
for (Function::iterator BB = F.begin(),
@ -130,33 +130,33 @@ namespace {
if (!CI->getCalledFunction() ||
!CI->getCalledFunction()->getIntrinsicID())
Calls.push_back(CI);
if (Calls.empty())
return 0;
// Create a cleanup block.
BasicBlock *CleanupBB = BasicBlock::Create(CleanupBBName, &F);
UnwindInst *UI = new UnwindInst(CleanupBB);
// Transform the 'call' instructions into 'invoke's branching to the
// cleanup block. Go in reverse order to make prettier BB names.
SmallVector<Value*,16> Args;
for (unsigned I = Calls.size(); I != 0; ) {
CallInst *CI = cast<CallInst>(Calls[--I]);
// Split the basic block containing the function call.
BasicBlock *CallBB = CI->getParent();
BasicBlock *NewBB =
CallBB->splitBasicBlock(CI, CallBB->getName() + ".cont");
// Remove the unconditional branch inserted at the end of CallBB.
CallBB->getInstList().pop_back();
NewBB->getInstList().remove(CI);
// Create a new invoke instruction.
Args.clear();
Args.append(CI->op_begin() + 1, CI->op_end());
InvokeInst *II = InvokeInst::Create(CI->getOperand(0),
NewBB, CleanupBB,
Args.begin(), Args.end(),
@ -166,7 +166,7 @@ namespace {
CI->replaceAllUsesWith(II);
delete CI;
}
Builder.SetInsertPoint(UI->getParent(), UI);
return &Builder;
}
@ -185,9 +185,9 @@ ShadowStackGC::ShadowStackGC() : Head(0), StackEntryTy(0) {
Constant *ShadowStackGC::GetFrameMap(Function &F) {
// doInitialization creates the abstract type of this value.
Type *VoidPtr = PointerType::getUnqual(Type::Int8Ty);
// Truncate the ShadowStackDescriptor if some metadata is null.
unsigned NumMeta = 0;
SmallVector<Constant*,16> Metadata;
@ -197,33 +197,33 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) {
NumMeta = I + 1;
Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr));
}
Constant *BaseElts[] = {
ConstantInt::get(Type::Int32Ty, Roots.size(), false),
ConstantInt::get(Type::Int32Ty, NumMeta, false),
};
Constant *DescriptorElts[] = {
ConstantStruct::get(BaseElts, 2),
ConstantArray::get(ArrayType::get(VoidPtr, NumMeta),
Metadata.begin(), NumMeta)
};
Constant *FrameMap = ConstantStruct::get(DescriptorElts, 2);
std::string TypeName("gc_map.");
TypeName += utostr(NumMeta);
F.getParent()->addTypeName(TypeName, FrameMap->getType());
// FIXME: Is this actually dangerous as WritingAnLLVMPass.html claims? Seems
// that, short of multithreaded LLVM, it should be safe; all that is
// necessary is that a simple Module::iterator loop not be invalidated.
// Appending to the GlobalVariable list is safe in that sense.
//
//
// All of the output passes emit globals last. The ExecutionEngine
// explicitly supports adding globals to the module after
// initialization.
//
//
// Still, if it isn't deemed acceptable, then this transformation needs
// to be a ModulePass (which means it cannot be in the 'llc' pipeline
// (which uses a FunctionPassManager (which segfaults (not asserts) if
@ -232,7 +232,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) {
GlobalVariable::InternalLinkage,
FrameMap, "__gc_" + F.getName(),
F.getParent());
Constant *GEPIndices[2] = { ConstantInt::get(Type::Int32Ty, 0),
ConstantInt::get(Type::Int32Ty, 0) };
return ConstantExpr::getGetElementPtr(GV, GEPIndices, 2);
@ -245,11 +245,11 @@ const Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) {
for (size_t I = 0; I != Roots.size(); I++)
EltTys.push_back(Roots[I].second->getAllocatedType());
Type *Ty = StructType::get(EltTys);
std::string TypeName("gc_stackentry.");
TypeName += F.getName();
F.getParent()->addTypeName(TypeName, Ty);
return Ty;
}
@ -267,25 +267,25 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) {
StructType *FrameMapTy = StructType::get(EltTys);
M.addTypeName("gc_map", FrameMapTy);
PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy);
// struct StackEntry {
// ShadowStackEntry *Next; // Caller's stack entry.
// FrameMap *Map; // Pointer to constant FrameMap.
// void *Roots[]; // Stack roots (in-place array, so we pretend).
// };
OpaqueType *RecursiveTy = OpaqueType::get();
EltTys.clear();
EltTys.push_back(PointerType::getUnqual(RecursiveTy));
EltTys.push_back(FrameMapPtrTy);
PATypeHolder LinkTyH = StructType::get(EltTys);
RecursiveTy->refineAbstractTypeTo(LinkTyH.get());
StackEntryTy = cast<StructType>(LinkTyH.get());
const PointerType *StackEntryPtrTy = PointerType::getUnqual(StackEntryTy);
M.addTypeName("gc_stackentry", LinkTyH.get()); // FIXME: Is this safe from
// a FunctionPass?
// Get the root chain if it already exists.
Head = M.getGlobalVariable("llvm_gc_root_chain");
if (!Head) {
@ -299,7 +299,7 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) {
Head->setInitializer(Constant::getNullValue(StackEntryPtrTy));
Head->setLinkage(GlobalValue::LinkOnceLinkage);
}
return true;
}
@ -313,11 +313,11 @@ void ShadowStackGC::CollectRoots(Function &F) {
// FIXME: Account for original alignment. Could fragment the root array.
// Approach 1: Null initialize empty slots at runtime. Yuck.
// Approach 2: Emit a map of the array instead of just a count.
assert(Roots.empty() && "Not cleaned up?");
SmallVector<std::pair<CallInst*,AllocaInst*>,16> MetaRoots;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;)
if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++))
@ -330,7 +330,7 @@ void ShadowStackGC::CollectRoots(Function &F) {
else
MetaRoots.push_back(Pair);
}
// Number roots with metadata (usually empty) at the beginning, so that the
// FrameMap::Meta array can be elided.
Roots.insert(Roots.begin(), MetaRoots.begin(), MetaRoots.end());
@ -343,9 +343,9 @@ ShadowStackGC::CreateGEP(IRBuilder<> &B, Value *BasePtr,
ConstantInt::get(Type::Int32Ty, Idx),
ConstantInt::get(Type::Int32Ty, Idx2) };
Value* Val = B.CreateGEP(BasePtr, Indices, Indices + 3, Name);
assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
return dyn_cast<GetElementPtrInst>(Val);
}
@ -355,7 +355,7 @@ ShadowStackGC::CreateGEP(IRBuilder<> &B, Value *BasePtr,
Value *Indices[] = { ConstantInt::get(Type::Int32Ty, 0),
ConstantInt::get(Type::Int32Ty, Idx) };
Value *Val = B.CreateGEP(BasePtr, Indices, Indices + 2, Name);
assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
return dyn_cast<GetElementPtrInst>(Val);
@ -365,55 +365,55 @@ ShadowStackGC::CreateGEP(IRBuilder<> &B, Value *BasePtr,
bool ShadowStackGC::performCustomLowering(Function &F) {
// Find calls to llvm.gcroot.
CollectRoots(F);
// If there are no roots in this function, then there is no need to add a
// stack map entry for it.
if (Roots.empty())
return false;
// Build the constant map and figure the type of the shadow stack entry.
Value *FrameMap = GetFrameMap(F);
const Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F);
// Build the shadow stack entry at the very start of the function.
BasicBlock::iterator IP = F.getEntryBlock().begin();
IRBuilder<> AtEntry(IP->getParent(), IP);
Instruction *StackEntry = AtEntry.CreateAlloca(ConcreteStackEntryTy, 0,
"gc_frame");
while (isa<AllocaInst>(IP)) ++IP;
AtEntry.SetInsertPoint(IP->getParent(), IP);
// Initialize the map pointer and load the current head of the shadow stack.
Instruction *CurrentHead = AtEntry.CreateLoad(Head, "gc_currhead");
Instruction *EntryMapPtr = CreateGEP(AtEntry, StackEntry,0,1,"gc_frame.map");
AtEntry.CreateStore(FrameMap, EntryMapPtr);
// After all the allocas...
for (unsigned I = 0, E = Roots.size(); I != E; ++I) {
// For each root, find the corresponding slot in the aggregate...
Value *SlotPtr = CreateGEP(AtEntry, StackEntry, 1 + I, "gc_root");
// And use it in lieu of the alloca.
AllocaInst *OriginalAlloca = Roots[I].second;
SlotPtr->takeName(OriginalAlloca);
OriginalAlloca->replaceAllUsesWith(SlotPtr);
}
// Move past the original stores inserted by GCStrategy::InitRoots. This isn't
// really necessary (the collector would never see the intermediate state at
// runtime), but it's nicer not to push the half-initialized entry onto the
// shadow stack.
while (isa<StoreInst>(IP)) ++IP;
AtEntry.SetInsertPoint(IP->getParent(), IP);
// Push the entry onto the shadow stack.
Instruction *EntryNextPtr = CreateGEP(AtEntry,StackEntry,0,0,"gc_frame.next");
Instruction *NewHeadVal = CreateGEP(AtEntry,StackEntry, 0, "gc_newhead");
AtEntry.CreateStore(CurrentHead, EntryNextPtr);
AtEntry.CreateStore(NewHeadVal, Head);
// For each instruction that escapes...
EscapeEnumerator EE(F, "gc_cleanup");
while (IRBuilder<> *AtExit = EE.Next()) {
@ -424,7 +424,7 @@ bool ShadowStackGC::performCustomLowering(Function &F) {
Value *SavedHead = AtExit->CreateLoad(EntryNextPtr2, "gc_savedhead");
AtExit->CreateStore(SavedHead, Head);
}
// Delete the original allocas (which are no longer used) and the intrinsic
// calls (which are no longer valid). Doing this last avoids invalidating
// iterators.
@ -432,7 +432,7 @@ bool ShadowStackGC::performCustomLowering(Function &F) {
Roots[I].first->eraseFromParent();
Roots[I].second->eraseFromParent();
}
Roots.clear();
return true;
}

View File

@ -26,13 +26,13 @@ static cl::opt<const TargetMachineRegistry::entry*, false,
MArch("march", cl::desc("Architecture to generate assembly for:"));
static cl::opt<std::string>
MCPU("mcpu",
MCPU("mcpu",
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
cl::value_desc("cpu-name"),
cl::init(""));
static cl::list<std::string>
MAttrs("mattr",
MAttrs("mattr",
cl::CommaSeparated,
cl::desc("Target specific attributes (-mattr=help for details)"),
cl::value_desc("a1,+a2,-a3,..."));

View File

@ -53,7 +53,7 @@ OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
static cl::opt<bool> Fast("fast",
static cl::opt<bool> Fast("fast",
cl::desc("Generate code quickly, potentially sacrificing code quality"));
static cl::opt<std::string>
@ -64,13 +64,13 @@ static cl::opt<const TargetMachineRegistry::entry*, false,
MArch("march", cl::desc("Architecture to generate code for:"));
static cl::opt<std::string>
MCPU("mcpu",
MCPU("mcpu",
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
cl::value_desc("cpu-name"),
cl::init(""));
static cl::list<std::string>
MAttrs("mattr",
MAttrs("mattr",
cl::CommaSeparated,
cl::desc("Target specific attributes (-mattr=help for details)"),
cl::value_desc("a1,+a2,-a3,..."));
@ -134,14 +134,14 @@ static raw_ostream *GetOutputStream(const char *ProgName) {
return Out;
}
if (InputFilename == "-") {
OutputFilename = "-";
return &outs();
}
OutputFilename = GetFileNameRoot(InputFilename);
bool Binary = false;
switch (FileType) {
case TargetMachine::AssemblyFile:
@ -164,7 +164,7 @@ static raw_ostream *GetOutputStream(const char *ProgName) {
Binary = true;
break;
}
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << ProgName << ": error opening '" << OutputFilename
@ -172,11 +172,11 @@ static raw_ostream *GetOutputStream(const char *ProgName) {
<< "Use -f command line argument to force output\n";
return 0;
}
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
std::string error;
raw_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), Binary, error);
if (!error.empty()) {
@ -184,7 +184,7 @@ static raw_ostream *GetOutputStream(const char *ProgName) {
delete Out;
return 0;
}
return Out;
}
@ -198,7 +198,7 @@ int main(int argc, char **argv) {
// Load the module to be compiled...
std::string ErrorMessage;
std::auto_ptr<Module> M;
std::auto_ptr<MemoryBuffer> Buffer(
MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage));
if (Buffer.get())
@ -209,11 +209,11 @@ int main(int argc, char **argv) {
return 1;
}
Module &mod = *M.get();
// If we are supposed to override the target triple, do so now.
if (!TargetTriple.empty())
mod.setTargetTriple(TargetTriple);
// Allocate target machine. First, check whether the user has
// explicitly specified an architecture to compile for.
if (MArch == 0) {
@ -236,7 +236,7 @@ int main(int argc, char **argv) {
Features.AddFeature(MAttrs[i]);
FeaturesStr = Features.getString();
}
std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, FeaturesStr));
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
@ -244,7 +244,7 @@ int main(int argc, char **argv) {
// Figure out where we are going to send the output...
raw_ostream *Out = GetOutputStream(argv[0]);
if (Out == 0) return 1;
// If this target requires addPassesToEmitWholeFile, do it now. This is
// used by strange things like the C backend.
if (Target.WantsWholeFile()) {
@ -252,7 +252,7 @@ int main(int argc, char **argv) {
PM.add(new TargetData(*Target.getTargetData()));
if (!NoVerify)
PM.add(createVerifierPass());
// Ask the target to add backend passes as necessary.
if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
std::cerr << argv[0] << ": target does not support generation of this"
@ -268,12 +268,12 @@ int main(int argc, char **argv) {
ExistingModuleProvider Provider(M.release());
FunctionPassManager Passes(&Provider);
Passes.add(new TargetData(*Target.getTargetData()));
#ifndef NDEBUG
if (!NoVerify)
Passes.add(createVerifierPass());
#endif
// Ask the target to add backend passes as necessary.
MachineCodeEmitter *MCE = 0;
@ -306,18 +306,18 @@ int main(int argc, char **argv) {
sys::Path(OutputFilename).eraseFromDisk();
return 1;
}
Passes.doInitialization();
// Run our queue of passes all at once now, efficiently.
// TODO: this could lazily stream functions out of the module.
for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
if (!I->isDeclaration())
Passes.run(*I);
Passes.doFinalization();
}
// Delete the ostream if it's not a stdout stream
if (Out != &outs()) delete Out;