2017-10-11 06:33:29 +08:00
|
|
|
//===- SafeStackLayout.h - SafeStack frame layout --------------*- C++ -*--===//
|
2016-06-30 04:37:43 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-06-30 04:37:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H
|
|
|
|
#define LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H
|
|
|
|
|
2017-10-11 06:33:29 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2020-06-15 17:26:28 +08:00
|
|
|
#include "llvm/Analysis/StackLifetime.h"
|
2016-06-30 04:37:43 +08:00
|
|
|
|
|
|
|
namespace llvm {
|
2017-10-11 06:33:29 +08:00
|
|
|
|
|
|
|
class raw_ostream;
|
|
|
|
class Value;
|
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
namespace safestack {
|
|
|
|
|
|
|
|
/// Compute the layout of an unsafe stack frame.
|
|
|
|
class StackLayout {
|
2021-12-10 05:20:06 +08:00
|
|
|
Align MaxAlignment;
|
2016-06-30 04:37:43 +08:00
|
|
|
|
|
|
|
struct StackRegion {
|
|
|
|
unsigned Start;
|
|
|
|
unsigned End;
|
2020-06-15 17:37:19 +08:00
|
|
|
StackLifetime::LiveRange Range;
|
2017-10-11 06:33:29 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
StackRegion(unsigned Start, unsigned End,
|
2020-06-15 17:37:19 +08:00
|
|
|
const StackLifetime::LiveRange &Range)
|
2016-06-30 04:37:43 +08:00
|
|
|
: Start(Start), End(End), Range(Range) {}
|
|
|
|
};
|
2017-10-11 06:33:29 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
/// The list of current stack regions, sorted by StackRegion::Start.
|
|
|
|
SmallVector<StackRegion, 16> Regions;
|
|
|
|
|
|
|
|
struct StackObject {
|
|
|
|
const Value *Handle;
|
2021-09-25 06:54:17 +08:00
|
|
|
unsigned Size;
|
2021-12-10 05:20:06 +08:00
|
|
|
Align Alignment;
|
2020-06-15 17:37:19 +08:00
|
|
|
StackLifetime::LiveRange Range;
|
2016-06-30 04:37:43 +08:00
|
|
|
};
|
2017-10-11 06:33:29 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
SmallVector<StackObject, 8> StackObjects;
|
|
|
|
|
|
|
|
DenseMap<const Value *, unsigned> ObjectOffsets;
|
2021-12-10 05:20:06 +08:00
|
|
|
DenseMap<const Value *, Align> ObjectAlignments;
|
2016-06-30 04:37:43 +08:00
|
|
|
|
|
|
|
void layoutObject(StackObject &Obj);
|
|
|
|
|
|
|
|
public:
|
2021-09-25 06:54:17 +08:00
|
|
|
StackLayout(uint64_t StackAlignment) : MaxAlignment(StackAlignment) {}
|
2017-10-11 06:33:29 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
/// Add an object to the stack frame. Value pointer is opaque and used as a
|
|
|
|
/// handle to retrieve the object's offset in the frame later.
|
2021-12-10 05:20:06 +08:00
|
|
|
void addObject(const Value *V, unsigned Size, Align Alignment,
|
2020-06-15 17:37:19 +08:00
|
|
|
const StackLifetime::LiveRange &Range);
|
2016-06-30 04:37:43 +08:00
|
|
|
|
|
|
|
/// Run the layout computation for all previously added objects.
|
|
|
|
void computeLayout();
|
|
|
|
|
|
|
|
/// Returns the offset to the object start in the stack frame.
|
|
|
|
unsigned getObjectOffset(const Value *V) { return ObjectOffsets[V]; }
|
|
|
|
|
[SafeStack] Use updated CreateMemCpy API to set more accurate source and destination alignments.
Summary:
This change is part of step five in the series of changes to remove alignment argument from
memcpy/memmove/memset in favour of alignment attributes. In particular, this changes the
creation of memcpys in the SafeStack pass to set the alignment of the destination object to
its stack alignment while separately setting the source byval arguments alignment to its
alignment.
Steps:
Step 1) Remove alignment parameter and create alignment parameter attributes for
memcpy/memmove/memset. ( rL322965, rC322964, rL322963 )
Step 2) Expand the IRBuilder API to allow creation of memcpy/memmove with differing
source and dest alignments. ( rL323597 )
Step 3) Update Clang to use the new IRBuilder API. ( rC323617 )
Step 4) Update Polly to use the new IRBuilder API. ( rL323618 )
Step 5) Update LLVM passes that create memcpy/memmove calls to use the new IRBuilder API,
and those that use use MemIntrinsicInst::[get|set]Alignment() to use [get|set]DestAlignment()
and [get|set]SourceAlignment() instead. (rL323886, rL323891, rL324148, rL324273, rL324278,
rL324384, rL324395, rL324402, rL324626, rL324642, rL324653, rL324654, rL324773, rL324774,
rL324781, rL324784 )
Step 6) Remove the single-alignment IRBuilder API for memcpy/memmove, and the
MemIntrinsicInst::[get|set]Alignment() methods.
Reference
http://lists.llvm.org/pipermail/llvm-dev/2015-August/089384.html
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html
Reviewers: eugenis, bollu
Reviewed By: eugenis
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D42710
llvm-svn: 324955
2018-02-13 06:39:47 +08:00
|
|
|
/// Returns the alignment of the object
|
2021-12-10 05:20:06 +08:00
|
|
|
Align getObjectAlignment(const Value *V) { return ObjectAlignments[V]; }
|
[SafeStack] Use updated CreateMemCpy API to set more accurate source and destination alignments.
Summary:
This change is part of step five in the series of changes to remove alignment argument from
memcpy/memmove/memset in favour of alignment attributes. In particular, this changes the
creation of memcpys in the SafeStack pass to set the alignment of the destination object to
its stack alignment while separately setting the source byval arguments alignment to its
alignment.
Steps:
Step 1) Remove alignment parameter and create alignment parameter attributes for
memcpy/memmove/memset. ( rL322965, rC322964, rL322963 )
Step 2) Expand the IRBuilder API to allow creation of memcpy/memmove with differing
source and dest alignments. ( rL323597 )
Step 3) Update Clang to use the new IRBuilder API. ( rC323617 )
Step 4) Update Polly to use the new IRBuilder API. ( rL323618 )
Step 5) Update LLVM passes that create memcpy/memmove calls to use the new IRBuilder API,
and those that use use MemIntrinsicInst::[get|set]Alignment() to use [get|set]DestAlignment()
and [get|set]SourceAlignment() instead. (rL323886, rL323891, rL324148, rL324273, rL324278,
rL324384, rL324395, rL324402, rL324626, rL324642, rL324653, rL324654, rL324773, rL324774,
rL324781, rL324784 )
Step 6) Remove the single-alignment IRBuilder API for memcpy/memmove, and the
MemIntrinsicInst::[get|set]Alignment() methods.
Reference
http://lists.llvm.org/pipermail/llvm-dev/2015-August/089384.html
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html
Reviewers: eugenis, bollu
Reviewed By: eugenis
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D42710
llvm-svn: 324955
2018-02-13 06:39:47 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
/// Returns the size of the entire frame.
|
|
|
|
unsigned getFrameSize() { return Regions.empty() ? 0 : Regions.back().End; }
|
|
|
|
|
|
|
|
/// Returns the alignment of the frame.
|
2021-12-10 05:20:06 +08:00
|
|
|
Align getFrameAlignment() { return MaxAlignment; }
|
2017-10-11 06:33:29 +08:00
|
|
|
|
2016-06-30 04:37:43 +08:00
|
|
|
void print(raw_ostream &OS);
|
|
|
|
};
|
|
|
|
|
2017-10-11 06:33:29 +08:00
|
|
|
} // end namespace safestack
|
|
|
|
|
|
|
|
} // end namespace llvm
|
2016-06-30 04:37:43 +08:00
|
|
|
|
|
|
|
#endif // LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H
|